github.com/matrixorigin/matrixone@v0.7.0/pkg/sql/parsers/tree/create.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tree 16 17 import ( 18 "fmt" 19 "strconv" 20 "strings" 21 ) 22 23 type CreateOption interface { 24 NodeFormatter 25 } 26 27 type createOptionImpl struct { 28 CreateOption 29 } 30 31 type CreateOptionDefault struct { 32 createOptionImpl 33 } 34 35 type CreateOptionCharset struct { 36 createOptionImpl 37 IsDefault bool 38 Charset string 39 } 40 41 func (node *CreateOptionCharset) Format(ctx *FmtCtx) { 42 if node.IsDefault { 43 ctx.WriteString("default ") 44 } 45 ctx.WriteString("character set ") 46 ctx.WriteString(node.Charset) 47 } 48 49 func NewCreateOptionCharset(c string) *CreateOptionCharset { 50 return &CreateOptionCharset{ 51 Charset: c, 52 } 53 } 54 55 type CreateOptionCollate struct { 56 createOptionImpl 57 IsDefault bool 58 Collate string 59 } 60 61 func (node *CreateOptionCollate) Format(ctx *FmtCtx) { 62 if node.IsDefault { 63 ctx.WriteString("default ") 64 } 65 ctx.WriteString("collate ") 66 ctx.WriteString(node.Collate) 67 } 68 69 func NewCreateOptionCollate(c string) *CreateOptionCollate { 70 return &CreateOptionCollate{ 71 Collate: c, 72 } 73 } 74 75 type CreateOptionEncryption struct { 76 createOptionImpl 77 Encrypt string 78 } 79 80 func (node *CreateOptionEncryption) Format(ctx *FmtCtx) { 81 ctx.WriteString("encryption ") 82 ctx.WriteString(node.Encrypt) 83 } 84 85 func NewCreateOptionEncryption(e string) *CreateOptionEncryption { 86 return &CreateOptionEncryption{ 87 Encrypt: e, 88 } 89 } 90 91 type CreateDatabase struct { 92 statementImpl 93 IfNotExists bool 94 Name Identifier 95 CreateOptions []CreateOption 96 } 97 98 func (node *CreateDatabase) Format(ctx *FmtCtx) { 99 ctx.WriteString("create database ") 100 if node.IfNotExists { 101 ctx.WriteString("if not exists ") 102 } 103 node.Name.Format(ctx) 104 if node.CreateOptions != nil { 105 for _, opt := range node.CreateOptions { 106 ctx.WriteByte(' ') 107 opt.Format(ctx) 108 } 109 } 110 } 111 112 func (node *CreateDatabase) GetStatementType() string { return "Create Database" } 113 func (node *CreateDatabase) GetQueryType() string { return QueryTypeDDL } 114 115 func NewCreateDatabase(ine bool, name Identifier, opts []CreateOption) *CreateDatabase { 116 return &CreateDatabase{ 117 IfNotExists: ine, 118 Name: name, 119 CreateOptions: opts, 120 } 121 } 122 123 type CreateTable struct { 124 statementImpl 125 /* 126 it is impossible to be the temporary table, the cluster table, 127 the normal table and the external table at the same time. 128 */ 129 Temporary bool 130 IsClusterTable bool 131 IfNotExists bool 132 Table TableName 133 Defs TableDefs 134 Options []TableOption 135 PartitionOption *PartitionOption 136 ClusterByOption *ClusterByOption 137 Param *ExternParam 138 } 139 140 func (node *CreateTable) Format(ctx *FmtCtx) { 141 ctx.WriteString("create") 142 if node.Temporary { 143 ctx.WriteString(" temporary") 144 } 145 if node.IsClusterTable { 146 ctx.WriteString(" cluster") 147 } 148 if node.Param != nil { 149 ctx.WriteString(" external") 150 } 151 152 ctx.WriteString(" table") 153 154 if node.IfNotExists { 155 ctx.WriteString(" if not exists") 156 } 157 158 ctx.WriteByte(' ') 159 node.Table.Format(ctx) 160 161 ctx.WriteString(" (") 162 for i, def := range node.Defs { 163 if i != 0 { 164 ctx.WriteString(",") 165 ctx.WriteByte(' ') 166 } 167 def.Format(ctx) 168 } 169 ctx.WriteByte(')') 170 171 if node.Options != nil { 172 prefix := " " 173 for _, t := range node.Options { 174 ctx.WriteString(prefix) 175 t.Format(ctx) 176 prefix = " " 177 } 178 } 179 180 if node.PartitionOption != nil { 181 ctx.WriteByte(' ') 182 node.PartitionOption.Format(ctx) 183 } 184 185 if node.Param != nil { 186 if len(node.Param.Option) == 0 { 187 ctx.WriteString(" infile ") 188 ctx.WriteString("'" + node.Param.Filepath + "'") 189 } else { 190 if node.Param.ScanType == S3 { 191 ctx.WriteString(" url s3option ") 192 } else { 193 ctx.WriteString(" infile ") 194 } 195 ctx.WriteString("{") 196 for i := 0; i < len(node.Param.Option); i += 2 { 197 switch strings.ToLower(node.Param.Option[i]) { 198 case "endpoint": 199 ctx.WriteString("'endpoint'='" + node.Param.Option[i+1] + "'") 200 case "region": 201 ctx.WriteString("'region'='" + node.Param.Option[i+1] + "'") 202 case "access_key_id": 203 ctx.WriteString("'access_key_id'='" + node.Param.Option[i+1] + "'") 204 case "secret_access_key": 205 ctx.WriteString("'secret_access_key'='" + node.Param.Option[i+1] + "'") 206 case "bucket": 207 ctx.WriteString("'bucket'='" + node.Param.Option[i+1] + "'") 208 case "filepath": 209 ctx.WriteString("'filepath'='" + node.Param.Option[i+1] + "'") 210 case "compression": 211 ctx.WriteString("'compression'='" + node.Param.Option[i+1] + "'") 212 case "format": 213 ctx.WriteString("'format'='" + node.Param.Option[i+1] + "'") 214 case "jsondata": 215 ctx.WriteString("'jsondata'='" + node.Param.Option[i+1] + "'") 216 } 217 if i != len(node.Param.Option)-2 { 218 ctx.WriteString(", ") 219 } 220 } 221 ctx.WriteString("}") 222 } 223 if node.Param.Tail.Fields != nil { 224 ctx.WriteByte(' ') 225 node.Param.Tail.Fields.Format(ctx) 226 } 227 228 if node.Param.Tail.Lines != nil { 229 ctx.WriteByte(' ') 230 node.Param.Tail.Lines.Format(ctx) 231 } 232 233 if node.Param.Tail.IgnoredLines != 0 { 234 ctx.WriteString(" ignore ") 235 ctx.WriteString(strconv.FormatUint(node.Param.Tail.IgnoredLines, 10)) 236 ctx.WriteString(" lines") 237 } 238 if node.Param.Tail.ColumnList != nil { 239 prefix := " (" 240 for _, c := range node.Param.Tail.ColumnList { 241 ctx.WriteString(prefix) 242 c.Format(ctx) 243 prefix = ", " 244 } 245 ctx.WriteByte(')') 246 } 247 if node.Param.Tail.Assignments != nil { 248 ctx.WriteString(" set ") 249 node.Param.Tail.Assignments.Format(ctx) 250 } 251 } 252 } 253 254 func (node *CreateTable) GetStatementType() string { return "Create Table" } 255 func (node *CreateTable) GetQueryType() string { return QueryTypeDDL } 256 257 type TableDef interface { 258 NodeFormatter 259 } 260 261 type tableDefImpl struct { 262 TableDef 263 } 264 265 // the list of table definitions 266 type TableDefs []TableDef 267 268 type ColumnTableDef struct { 269 tableDefImpl 270 Name *UnresolvedName 271 Type ResolvableTypeReference 272 Attributes []ColumnAttribute 273 } 274 275 func (node *ColumnTableDef) Format(ctx *FmtCtx) { 276 node.Name.Format(ctx) 277 278 ctx.WriteByte(' ') 279 node.Type.(*T).InternalType.Format(ctx) 280 281 if node.Attributes != nil { 282 prefix := " " 283 for _, a := range node.Attributes { 284 ctx.WriteString(prefix) 285 a.Format(ctx) 286 } 287 } 288 } 289 290 func NewColumnTableDef(n *UnresolvedName, t ResolvableTypeReference, a []ColumnAttribute) *ColumnTableDef { 291 return &ColumnTableDef{ 292 Name: n, 293 Type: t, 294 Attributes: a, 295 } 296 } 297 298 // column attribute 299 type ColumnAttribute interface { 300 NodeFormatter 301 } 302 303 type columnAttributeImpl struct { 304 ColumnAttribute 305 } 306 307 type AttributeNull struct { 308 columnAttributeImpl 309 Is bool //true NULL (default); false NOT NULL 310 } 311 312 func (node *AttributeNull) Format(ctx *FmtCtx) { 313 if node.Is { 314 ctx.WriteString("null") 315 } else { 316 ctx.WriteString("not null") 317 } 318 } 319 320 func NewAttributeNull(b bool) *AttributeNull { 321 return &AttributeNull{ 322 Is: b, 323 } 324 } 325 326 type AttributeDefault struct { 327 columnAttributeImpl 328 Expr Expr 329 } 330 331 func (node *AttributeDefault) Format(ctx *FmtCtx) { 332 ctx.WriteString("default ") 333 node.Expr.Format(ctx) 334 } 335 336 func NewAttributeDefault(e Expr) *AttributeDefault { 337 return &AttributeDefault{ 338 Expr: e, 339 } 340 } 341 342 type AttributeAutoIncrement struct { 343 columnAttributeImpl 344 IsAutoIncrement bool 345 } 346 347 func (node *AttributeAutoIncrement) Format(ctx *FmtCtx) { 348 ctx.WriteString("auto_increment") 349 } 350 351 func NewAttributeAutoIncrement() *AttributeAutoIncrement { 352 return &AttributeAutoIncrement{} 353 } 354 355 type AttributeUniqueKey struct { 356 columnAttributeImpl 357 } 358 359 func (node *AttributeUniqueKey) Format(ctx *FmtCtx) { 360 ctx.WriteString("unique key") 361 } 362 363 func NewAttributeUniqueKey() *AttributeUniqueKey { 364 return &AttributeUniqueKey{} 365 } 366 367 type AttributeUnique struct { 368 columnAttributeImpl 369 } 370 371 func (node *AttributeUnique) Format(ctx *FmtCtx) { 372 ctx.WriteString("unique") 373 } 374 375 func NewAttributeUnique() *AttributeUnique { 376 return &AttributeUnique{} 377 } 378 379 type AttributeKey struct { 380 columnAttributeImpl 381 } 382 383 func (node *AttributeKey) Format(ctx *FmtCtx) { 384 ctx.WriteString("key") 385 } 386 387 func NewAttributeKey() *AttributeKey { 388 return &AttributeKey{} 389 } 390 391 type AttributePrimaryKey struct { 392 columnAttributeImpl 393 } 394 395 func (node *AttributePrimaryKey) Format(ctx *FmtCtx) { 396 ctx.WriteString("primary key") 397 } 398 399 func NewAttributePrimaryKey() *AttributePrimaryKey { 400 return &AttributePrimaryKey{} 401 } 402 403 type AttributeComment struct { 404 columnAttributeImpl 405 CMT Expr 406 } 407 408 func (node *AttributeComment) Format(ctx *FmtCtx) { 409 ctx.WriteString("comment ") 410 node.CMT.Format(ctx) 411 } 412 413 func NewAttributeComment(c Expr) *AttributeComment { 414 return &AttributeComment{ 415 CMT: c, 416 } 417 } 418 419 type AttributeCollate struct { 420 columnAttributeImpl 421 Collate string 422 } 423 424 func (node *AttributeCollate) Format(ctx *FmtCtx) { 425 ctx.WriteString("collate ") 426 ctx.WriteString(node.Collate) 427 } 428 429 func NewAttributeCollate(c string) *AttributeCollate { 430 return &AttributeCollate{ 431 Collate: c, 432 } 433 } 434 435 type AttributeColumnFormat struct { 436 columnAttributeImpl 437 ColumnFormat string 438 } 439 440 func (node *AttributeColumnFormat) Format(ctx *FmtCtx) { 441 ctx.WriteString("format ") 442 ctx.WriteString(node.ColumnFormat) 443 } 444 445 func NewAttributeColumnFormat(f string) *AttributeColumnFormat { 446 return &AttributeColumnFormat{ 447 ColumnFormat: f, 448 } 449 } 450 451 type AttributeStorage struct { 452 columnAttributeImpl 453 Storage string 454 } 455 456 func (node *AttributeStorage) Format(ctx *FmtCtx) { 457 ctx.WriteString("storage ") 458 ctx.WriteString(node.Storage) 459 } 460 461 func NewAttributeStorage(s string) *AttributeStorage { 462 return &AttributeStorage{ 463 Storage: s, 464 } 465 } 466 467 type AttributeCheckConstraint struct { 468 columnAttributeImpl 469 Name string 470 Expr Expr 471 Enforced bool 472 } 473 474 func (node *AttributeCheckConstraint) Format(ctx *FmtCtx) { 475 ctx.WriteString("constraint") 476 if node.Name != "" { 477 ctx.WriteByte(' ') 478 ctx.WriteString(node.Name) 479 } 480 ctx.WriteString(" check") 481 ctx.WriteString(" (") 482 node.Expr.Format(ctx) 483 ctx.WriteString(") ") 484 485 if node.Enforced { 486 ctx.WriteString("enforced") 487 } else { 488 ctx.WriteString("not enforced") 489 } 490 } 491 492 func NewAttributeCheck(e Expr, f bool, n string) *AttributeCheckConstraint { 493 return &AttributeCheckConstraint{ 494 Name: n, 495 Expr: e, 496 Enforced: f, 497 } 498 } 499 500 type AttributeGeneratedAlways struct { 501 columnAttributeImpl 502 Expr Expr 503 Stored bool 504 } 505 506 func (node *AttributeGeneratedAlways) Format(ctx *FmtCtx) { 507 node.Expr.Format(ctx) 508 } 509 510 func NewAttributeGeneratedAlways(e Expr, s bool) *AttributeGeneratedAlways { 511 return &AttributeGeneratedAlways{ 512 Expr: e, 513 Stored: s, 514 } 515 } 516 517 type AttributeLowCardinality struct { 518 columnAttributeImpl 519 } 520 521 func (node *AttributeLowCardinality) Format(ctx *FmtCtx) { 522 ctx.WriteString("low_cardinality") 523 } 524 525 func NewAttributeLowCardinality() *AttributeLowCardinality { 526 return &AttributeLowCardinality{} 527 } 528 529 type KeyPart struct { 530 columnAttributeImpl 531 ColName *UnresolvedName 532 Length int 533 Direction Direction // asc or desc 534 Expr Expr 535 } 536 537 func (node *KeyPart) Format(ctx *FmtCtx) { 538 if node.ColName != nil { 539 node.ColName.Format(ctx) 540 } 541 if node.Length != 0 { 542 ctx.WriteByte('(') 543 if node.Length == -1 { 544 ctx.WriteString("0") 545 } else { 546 ctx.WriteString(strconv.Itoa(node.Length)) 547 } 548 ctx.WriteByte(')') 549 } 550 if node.Direction != DefaultDirection { 551 ctx.WriteByte(' ') 552 ctx.WriteString(node.Direction.String()) 553 return 554 } 555 if node.Expr != nil { 556 ctx.WriteByte('(') 557 node.Expr.Format(ctx) 558 ctx.WriteByte(')') 559 if node.Direction != DefaultDirection { 560 ctx.WriteByte(' ') 561 ctx.WriteString(node.Direction.String()) 562 } 563 } 564 } 565 566 func NewKeyPart(c *UnresolvedName, l int, e Expr) *KeyPart { 567 return &KeyPart{ 568 ColName: c, 569 Length: l, 570 Expr: e, 571 } 572 } 573 574 // in reference definition 575 type MatchType int 576 577 func (node *MatchType) ToString() string { 578 switch *node { 579 case MATCH_FULL: 580 return "full" 581 case MATCH_PARTIAL: 582 return "partial" 583 case MATCH_SIMPLE: 584 return "simple" 585 default: 586 return "Unknown MatchType" 587 } 588 } 589 590 const ( 591 MATCH_INVALID MatchType = iota 592 MATCH_FULL 593 MATCH_PARTIAL 594 MATCH_SIMPLE 595 ) 596 597 type ReferenceOptionType int 598 599 func (node *ReferenceOptionType) ToString() string { 600 switch *node { 601 case REFERENCE_OPTION_RESTRICT: 602 return "restrict" 603 case REFERENCE_OPTION_CASCADE: 604 return "cascade" 605 case REFERENCE_OPTION_SET_NULL: 606 return "set null" 607 case REFERENCE_OPTION_NO_ACTION: 608 return "no action" 609 case REFERENCE_OPTION_SET_DEFAULT: 610 return "set default" 611 default: 612 return "Unknown ReferenceOptionType" 613 } 614 } 615 616 // Reference option 617 const ( 618 REFERENCE_OPTION_INVALID ReferenceOptionType = iota 619 REFERENCE_OPTION_RESTRICT 620 REFERENCE_OPTION_CASCADE 621 REFERENCE_OPTION_SET_NULL 622 REFERENCE_OPTION_NO_ACTION 623 REFERENCE_OPTION_SET_DEFAULT 624 ) 625 626 type AttributeReference struct { 627 columnAttributeImpl 628 TableName *TableName 629 KeyParts []*KeyPart 630 Match MatchType 631 OnDelete ReferenceOptionType 632 OnUpdate ReferenceOptionType 633 } 634 635 func (node *AttributeReference) Format(ctx *FmtCtx) { 636 ctx.WriteString("references ") 637 node.TableName.Format(ctx) 638 if node.KeyParts != nil { 639 ctx.WriteByte('(') 640 prefix := "" 641 for _, k := range node.KeyParts { 642 ctx.WriteString(prefix) 643 k.Format(ctx) 644 prefix = ", " 645 } 646 ctx.WriteByte(')') 647 } 648 if node.Match != MATCH_INVALID { 649 ctx.WriteString(" match ") 650 ctx.WriteString(node.Match.ToString()) 651 } 652 if node.OnDelete != REFERENCE_OPTION_INVALID { 653 ctx.WriteString(" on delete ") 654 ctx.WriteString(node.OnDelete.ToString()) 655 } 656 if node.OnUpdate != REFERENCE_OPTION_INVALID { 657 ctx.WriteString(" on update ") 658 ctx.WriteString(node.OnUpdate.ToString()) 659 } 660 } 661 662 func NewAttributeReference(t *TableName, kps []*KeyPart, m MatchType, 663 od ReferenceOptionType, ou ReferenceOptionType) *AttributeReference { 664 return &AttributeReference{ 665 TableName: t, 666 KeyParts: kps, 667 Match: m, 668 OnDelete: od, 669 OnUpdate: ou, 670 } 671 } 672 673 type ReferenceOnRecord struct { 674 OnDelete ReferenceOptionType 675 OnUpdate ReferenceOptionType 676 } 677 678 type AttributeAutoRandom struct { 679 columnAttributeImpl 680 BitLength int 681 } 682 683 func NewAttributeAutoRandom(b int) *AttributeAutoRandom { 684 return &AttributeAutoRandom{ 685 BitLength: b, 686 } 687 } 688 689 type AttributeOnUpdate struct { 690 columnAttributeImpl 691 Expr Expr 692 } 693 694 func (node *AttributeOnUpdate) Format(ctx *FmtCtx) { 695 ctx.WriteString("on update ") 696 node.Expr.Format(ctx) 697 } 698 699 func NewAttributeOnUpdate(e Expr) *AttributeOnUpdate { 700 return &AttributeOnUpdate{ 701 Expr: e, 702 } 703 } 704 705 type IndexType int 706 707 func (it IndexType) ToString() string { 708 switch it { 709 case INDEX_TYPE_BTREE: 710 return "btree" 711 case INDEX_TYPE_HASH: 712 return "hash" 713 case INDEX_TYPE_RTREE: 714 return "rtree" 715 case INDEX_TYPE_BSI: 716 return "bsi" 717 case INDEX_TYPE_ZONEMAP: 718 return "zonemap" 719 default: 720 return "Unknown IndexType" 721 } 722 } 723 724 const ( 725 INDEX_TYPE_INVALID IndexType = iota 726 INDEX_TYPE_BTREE 727 INDEX_TYPE_HASH 728 INDEX_TYPE_RTREE 729 INDEX_TYPE_BSI 730 INDEX_TYPE_ZONEMAP 731 ) 732 733 type VisibleType int 734 735 const ( 736 VISIBLE_TYPE_INVALID VisibleType = iota 737 VISIBLE_TYPE_VISIBLE 738 VISIBLE_TYPE_INVISIBLE 739 ) 740 741 func (vt VisibleType) ToString() string { 742 switch vt { 743 case VISIBLE_TYPE_VISIBLE: 744 return "visible" 745 case VISIBLE_TYPE_INVISIBLE: 746 return "invisible" 747 default: 748 return "Unknown VisibleType" 749 } 750 } 751 752 type IndexOption struct { 753 NodeFormatter 754 KeyBlockSize uint64 755 IType IndexType 756 ParserName string 757 Comment string 758 Visible VisibleType 759 EngineAttribute string 760 SecondaryEngineAttribute string 761 } 762 763 // Must follow the following sequence when test 764 func (node *IndexOption) Format(ctx *FmtCtx) { 765 if node.KeyBlockSize != 0 { 766 ctx.WriteString("KEY_BLOCK_SIZE ") 767 ctx.WriteString(strconv.FormatUint(node.KeyBlockSize, 10)) 768 ctx.WriteByte(' ') 769 } 770 if node.ParserName != "" { 771 ctx.WriteString("with parser ") 772 ctx.WriteString(node.ParserName) 773 ctx.WriteByte(' ') 774 } 775 if node.Comment != "" { 776 ctx.WriteString("comment ") 777 ctx.WriteString(node.Comment) 778 ctx.WriteByte(' ') 779 } 780 if node.Visible != VISIBLE_TYPE_INVALID { 781 ctx.WriteString(node.Visible.ToString()) 782 } 783 } 784 785 func NewIndexOption(k uint64, i IndexType, p string, c string, v VisibleType, e string, se string) *IndexOption { 786 return &IndexOption{ 787 KeyBlockSize: k, 788 IType: i, 789 ParserName: p, 790 Comment: c, 791 Visible: v, 792 EngineAttribute: e, 793 SecondaryEngineAttribute: se, 794 } 795 } 796 797 type PrimaryKeyIndex struct { 798 tableDefImpl 799 KeyParts []*KeyPart 800 Name string 801 Empty bool 802 IndexOption *IndexOption 803 } 804 805 func (node *PrimaryKeyIndex) Format(ctx *FmtCtx) { 806 ctx.WriteString("primary key") 807 if node.Name != "" { 808 ctx.WriteByte(' ') 809 ctx.WriteString(node.Name) 810 } 811 if !node.Empty { 812 ctx.WriteString(" using none") 813 } 814 if node.KeyParts != nil { 815 prefix := " (" 816 for _, k := range node.KeyParts { 817 ctx.WriteString(prefix) 818 k.Format(ctx) 819 prefix = ", " 820 } 821 ctx.WriteByte(')') 822 } 823 if node.IndexOption != nil { 824 ctx.WriteByte(' ') 825 node.IndexOption.Format(ctx) 826 } 827 } 828 829 func NewPrimaryKeyIndex(k []*KeyPart, n string, e bool, io *IndexOption) *PrimaryKeyIndex { 830 return &PrimaryKeyIndex{ 831 KeyParts: k, 832 Name: n, 833 Empty: e, 834 IndexOption: io, 835 } 836 } 837 838 type Index struct { 839 tableDefImpl 840 IfNotExists bool 841 KeyParts []*KeyPart 842 Name string 843 KeyType IndexType 844 IndexOption *IndexOption 845 } 846 847 func (node *Index) Format(ctx *FmtCtx) { 848 ctx.WriteString("index") 849 if node.IfNotExists { 850 ctx.WriteString(" if not exists") 851 } 852 if node.Name != "" { 853 ctx.WriteByte(' ') 854 ctx.WriteString(node.Name) 855 } 856 if node.KeyType != INDEX_TYPE_INVALID { 857 ctx.WriteString(" using ") 858 ctx.WriteString(node.KeyType.ToString()) 859 } 860 if node.KeyParts != nil { 861 prefix := " (" 862 for _, k := range node.KeyParts { 863 ctx.WriteString(prefix) 864 k.Format(ctx) 865 prefix = ", " 866 } 867 ctx.WriteByte(')') 868 } 869 if node.IndexOption != nil { 870 ctx.WriteByte(' ') 871 node.IndexOption.Format(ctx) 872 } 873 } 874 875 func NewIndex(k []*KeyPart, n string, t IndexType, io *IndexOption) *Index { 876 return &Index{ 877 KeyParts: k, 878 Name: n, 879 KeyType: t, 880 IndexOption: io, 881 } 882 } 883 884 type UniqueIndex struct { 885 tableDefImpl 886 KeyParts []*KeyPart 887 Name string 888 Empty bool 889 IndexOption *IndexOption 890 } 891 892 func (node *UniqueIndex) Format(ctx *FmtCtx) { 893 ctx.WriteString("unique key") 894 if node.Name != "" { 895 ctx.WriteByte(' ') 896 ctx.WriteString(node.Name) 897 } 898 if !node.Empty { 899 ctx.WriteString(" using none") 900 } 901 if node.KeyParts != nil { 902 prefix := " (" 903 for _, k := range node.KeyParts { 904 ctx.WriteString(prefix) 905 k.Format(ctx) 906 prefix = ", " 907 } 908 ctx.WriteByte(')') 909 } 910 if node.IndexOption != nil { 911 ctx.WriteByte(' ') 912 node.IndexOption.Format(ctx) 913 } 914 } 915 916 func NewUniqueIndex(k []*KeyPart, n string, e bool, io *IndexOption) *UniqueIndex { 917 return &UniqueIndex{ 918 KeyParts: k, 919 Name: n, 920 Empty: e, 921 IndexOption: io, 922 } 923 } 924 925 type ForeignKey struct { 926 tableDefImpl 927 IfNotExists bool 928 KeyParts []*KeyPart 929 Name string 930 Refer *AttributeReference 931 Empty bool 932 } 933 934 func (node *ForeignKey) Format(ctx *FmtCtx) { 935 ctx.WriteString("foreign key") 936 if node.IfNotExists { 937 ctx.WriteString(" if not exists") 938 } 939 if node.Name != "" { 940 ctx.WriteByte(' ') 941 ctx.WriteString(node.Name) 942 } 943 if !node.Empty { 944 ctx.WriteString(" using none") 945 } 946 if node.KeyParts != nil { 947 prefix := " (" 948 for _, k := range node.KeyParts { 949 ctx.WriteString(prefix) 950 k.Format(ctx) 951 prefix = ", " 952 } 953 ctx.WriteByte(')') 954 } 955 if node.Refer != nil { 956 ctx.WriteByte(' ') 957 node.Refer.Format(ctx) 958 } 959 } 960 961 func NewForeignKey(ine bool, k []*KeyPart, n string, r *AttributeReference, e bool) *ForeignKey { 962 return &ForeignKey{ 963 IfNotExists: ine, 964 KeyParts: k, 965 Name: n, 966 Refer: r, 967 Empty: e, 968 } 969 } 970 971 type FullTextIndex struct { 972 tableDefImpl 973 KeyParts []*KeyPart 974 Name string 975 Empty bool 976 IndexOption *IndexOption 977 } 978 979 func (node *FullTextIndex) Format(ctx *FmtCtx) { 980 ctx.WriteString("fulltext") 981 if node.Name != "" { 982 ctx.WriteByte(' ') 983 ctx.WriteString(node.Name) 984 } 985 if !node.Empty { 986 ctx.WriteString(" using none") 987 } 988 if node.KeyParts != nil { 989 prefix := " (" 990 for _, k := range node.KeyParts { 991 ctx.WriteString(prefix) 992 k.Format(ctx) 993 prefix = ", " 994 } 995 ctx.WriteByte(')') 996 } 997 if node.IndexOption != nil { 998 ctx.WriteByte(' ') 999 node.IndexOption.Format(ctx) 1000 } 1001 } 1002 1003 func NewFullTextIndex(k []*KeyPart, n string, e bool, io *IndexOption) *FullTextIndex { 1004 return &FullTextIndex{ 1005 KeyParts: k, 1006 Name: n, 1007 Empty: e, 1008 IndexOption: io, 1009 } 1010 } 1011 1012 type CheckIndex struct { 1013 tableDefImpl 1014 Expr Expr 1015 Enforced bool 1016 } 1017 1018 func (node *CheckIndex) Format(ctx *FmtCtx) { 1019 ctx.WriteString("check (") 1020 node.Expr.Format(ctx) 1021 ctx.WriteByte(')') 1022 if node.Enforced { 1023 ctx.WriteString(" enforced") 1024 } 1025 } 1026 1027 func NewCheckIndex(e Expr, en bool) *CheckIndex { 1028 return &CheckIndex{ 1029 Expr: e, 1030 Enforced: en, 1031 } 1032 } 1033 1034 type TableOption interface { 1035 NodeFormatter 1036 } 1037 1038 type tableOptionImpl struct { 1039 TableOption 1040 } 1041 1042 type TableOptionProperties struct { 1043 tableOptionImpl 1044 Preperties []Property 1045 } 1046 1047 func (node *TableOptionProperties) Format(ctx *FmtCtx) { 1048 ctx.WriteString("properties") 1049 if node.Preperties != nil { 1050 prefix := "(" 1051 for _, p := range node.Preperties { 1052 ctx.WriteString(prefix) 1053 p.Format(ctx) 1054 prefix = ", " 1055 } 1056 ctx.WriteByte(')') 1057 } 1058 } 1059 1060 type Property struct { 1061 Key string 1062 Value string 1063 } 1064 1065 func (node *Property) Format(ctx *FmtCtx) { 1066 ctx.WriteString(node.Key) 1067 ctx.WriteString(" = ") 1068 ctx.WriteString(node.Value) 1069 } 1070 1071 type TableOptionEngine struct { 1072 tableOptionImpl 1073 Engine string 1074 } 1075 1076 func (node *TableOptionEngine) Format(ctx *FmtCtx) { 1077 ctx.WriteString("engine = ") 1078 ctx.WriteString(node.Engine) 1079 } 1080 1081 func NewTableOptionEngine(s string) *TableOptionEngine { 1082 return &TableOptionEngine{ 1083 Engine: s, 1084 } 1085 } 1086 1087 type TableOptionSecondaryEngine struct { 1088 tableOptionImpl 1089 Engine string 1090 } 1091 1092 func (node *TableOptionSecondaryEngine) Format(ctx *FmtCtx) { 1093 ctx.WriteString("engine = ") 1094 ctx.WriteString(node.Engine) 1095 } 1096 1097 func NewTableOptionSecondaryEngine(s string) *TableOptionSecondaryEngine { 1098 return &TableOptionSecondaryEngine{ 1099 Engine: s, 1100 } 1101 } 1102 1103 type TableOptionSecondaryEngineNull struct { 1104 tableOptionImpl 1105 } 1106 1107 func NewTableOptionSecondaryEngineNull() *TableOptionSecondaryEngineNull { 1108 return &TableOptionSecondaryEngineNull{} 1109 } 1110 1111 type TableOptionCharset struct { 1112 tableOptionImpl 1113 Charset string 1114 } 1115 1116 func (node *TableOptionCharset) Format(ctx *FmtCtx) { 1117 ctx.WriteString("charset = ") 1118 ctx.WriteString(node.Charset) 1119 } 1120 1121 func NewTableOptionCharset(s string) *TableOptionCharset { 1122 return &TableOptionCharset{Charset: s} 1123 } 1124 1125 type TableOptionCollate struct { 1126 tableOptionImpl 1127 Collate string 1128 } 1129 1130 func (node *TableOptionCollate) Format(ctx *FmtCtx) { 1131 ctx.WriteString("Collate = ") 1132 ctx.WriteString(node.Collate) 1133 } 1134 1135 func NewTableOptionCollate(s string) *TableOptionCollate { 1136 return &TableOptionCollate{ 1137 Collate: s, 1138 } 1139 } 1140 1141 type TableOptionAutoIncrement struct { 1142 tableOptionImpl 1143 Value uint64 1144 } 1145 1146 func (node *TableOptionAutoIncrement) Format(ctx *FmtCtx) { 1147 ctx.WriteString("auto_increment = ") 1148 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1149 } 1150 1151 func NewTableOptionAutoIncrement(v uint64) *TableOptionAutoIncrement { 1152 return &TableOptionAutoIncrement{ 1153 Value: v, 1154 } 1155 } 1156 1157 type TableOptionComment struct { 1158 tableOptionImpl 1159 Comment string 1160 } 1161 1162 func (node *TableOptionComment) Format(ctx *FmtCtx) { 1163 ctx.WriteString("comment = ") 1164 ctx.WriteString(node.Comment) 1165 } 1166 1167 func NewTableOptionComment(c string) *TableOptionComment { 1168 return &TableOptionComment{ 1169 Comment: c, 1170 } 1171 } 1172 1173 type TableOptionAvgRowLength struct { 1174 tableOptionImpl 1175 Length uint64 1176 } 1177 1178 func (node *TableOptionAvgRowLength) Format(ctx *FmtCtx) { 1179 ctx.WriteString("avg_row_length = ") 1180 ctx.WriteString(strconv.FormatUint(node.Length, 10)) 1181 } 1182 1183 func NewTableOptionAvgRowLength(l uint64) *TableOptionAvgRowLength { 1184 return &TableOptionAvgRowLength{ 1185 Length: l, 1186 } 1187 } 1188 1189 type TableOptionChecksum struct { 1190 tableOptionImpl 1191 Value uint64 1192 } 1193 1194 func (node *TableOptionChecksum) Format(ctx *FmtCtx) { 1195 ctx.WriteString("checksum = ") 1196 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1197 } 1198 1199 func NewTableOptionChecksum(v uint64) *TableOptionChecksum { 1200 return &TableOptionChecksum{ 1201 Value: v, 1202 } 1203 } 1204 1205 type TableOptionCompression struct { 1206 tableOptionImpl 1207 Compression string 1208 } 1209 1210 func (node *TableOptionCompression) Format(ctx *FmtCtx) { 1211 ctx.WriteString("compression = ") 1212 ctx.WriteString(node.Compression) 1213 } 1214 1215 func NewTableOptionCompression(c string) *TableOptionCompression { 1216 return &TableOptionCompression{ 1217 Compression: c, 1218 } 1219 } 1220 1221 type TableOptionConnection struct { 1222 tableOptionImpl 1223 Connection string 1224 } 1225 1226 func (node *TableOptionConnection) Format(ctx *FmtCtx) { 1227 ctx.WriteString("connection = ") 1228 ctx.WriteString(node.Connection) 1229 } 1230 1231 func NewTableOptionConnection(c string) *TableOptionConnection { 1232 return &TableOptionConnection{ 1233 Connection: c, 1234 } 1235 } 1236 1237 type TableOptionPassword struct { 1238 tableOptionImpl 1239 Password string 1240 } 1241 1242 func (node *TableOptionPassword) Format(ctx *FmtCtx) { 1243 ctx.WriteString("password = ") 1244 ctx.WriteString(node.Password) 1245 } 1246 1247 func NewTableOptionPassword(p string) *TableOptionPassword { 1248 return &TableOptionPassword{ 1249 Password: p, 1250 } 1251 } 1252 1253 type TableOptionKeyBlockSize struct { 1254 tableOptionImpl 1255 Value uint64 1256 } 1257 1258 func (node *TableOptionKeyBlockSize) Format(ctx *FmtCtx) { 1259 ctx.WriteString("key_block_size = ") 1260 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1261 } 1262 1263 func NewTableOptionKeyBlockSize(v uint64) *TableOptionKeyBlockSize { 1264 return &TableOptionKeyBlockSize{ 1265 Value: v, 1266 } 1267 } 1268 1269 type TableOptionMaxRows struct { 1270 tableOptionImpl 1271 Value uint64 1272 } 1273 1274 func (node *TableOptionMaxRows) Format(ctx *FmtCtx) { 1275 ctx.WriteString("max_rows = ") 1276 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1277 } 1278 1279 func NewTableOptionMaxRows(v uint64) *TableOptionMaxRows { 1280 return &TableOptionMaxRows{ 1281 Value: v, 1282 } 1283 } 1284 1285 type TableOptionMinRows struct { 1286 tableOptionImpl 1287 Value uint64 1288 } 1289 1290 func (node *TableOptionMinRows) Format(ctx *FmtCtx) { 1291 ctx.WriteString("min_rows = ") 1292 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1293 } 1294 1295 func NewTableOptionMinRows(v uint64) *TableOptionMinRows { 1296 return &TableOptionMinRows{ 1297 Value: v, 1298 } 1299 } 1300 1301 type TableOptionDelayKeyWrite struct { 1302 tableOptionImpl 1303 Value uint64 1304 } 1305 1306 func (node *TableOptionDelayKeyWrite) Format(ctx *FmtCtx) { 1307 ctx.WriteString("key_write = ") 1308 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1309 } 1310 1311 func NewTableOptionDelayKeyWrite(v uint64) *TableOptionDelayKeyWrite { 1312 return &TableOptionDelayKeyWrite{ 1313 Value: v, 1314 } 1315 } 1316 1317 type RowFormatType uint64 1318 1319 const ( 1320 ROW_FORMAT_DEFAULT RowFormatType = iota 1321 ROW_FORMAT_DYNAMIC 1322 ROW_FORMAT_FIXED 1323 ROW_FORMAT_COMPRESSED 1324 ROW_FORMAT_REDUNDANT 1325 ROW_FORMAT_COMPACT 1326 ) 1327 1328 func (node *RowFormatType) ToString() string { 1329 switch *node { 1330 case ROW_FORMAT_DEFAULT: 1331 return "default" 1332 case ROW_FORMAT_DYNAMIC: 1333 return "dynamic" 1334 case ROW_FORMAT_FIXED: 1335 return "fixed" 1336 case ROW_FORMAT_COMPRESSED: 1337 return "compressed" 1338 case ROW_FORMAT_REDUNDANT: 1339 return "redundant" 1340 case ROW_FORMAT_COMPACT: 1341 return "compact" 1342 default: 1343 return "Unknown RowFormatType" 1344 } 1345 } 1346 1347 type TableOptionRowFormat struct { 1348 tableOptionImpl 1349 Value RowFormatType 1350 } 1351 1352 func (node *TableOptionRowFormat) Format(ctx *FmtCtx) { 1353 ctx.WriteString("row_format = ") 1354 ctx.WriteString(node.Value.ToString()) 1355 } 1356 1357 func NewTableOptionRowFormat(v RowFormatType) *TableOptionRowFormat { 1358 return &TableOptionRowFormat{ 1359 Value: v, 1360 } 1361 } 1362 1363 type TableOptionStatsPersistent struct { 1364 tableOptionImpl 1365 Value uint64 1366 Default bool 1367 } 1368 1369 func (node *TableOptionStatsPersistent) Format(ctx *FmtCtx) { 1370 ctx.WriteString("stats_persistent = ") 1371 if node.Default { 1372 ctx.WriteString("default") 1373 } else { 1374 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1375 } 1376 } 1377 1378 func NewTableOptionStatsPersistent() *TableOptionStatsPersistent { 1379 return &TableOptionStatsPersistent{} 1380 } 1381 1382 type TableOptionStatsAutoRecalc struct { 1383 tableOptionImpl 1384 Value uint64 1385 Default bool //false -- see Value; true -- Value is useless 1386 } 1387 1388 func (node *TableOptionStatsAutoRecalc) Format(ctx *FmtCtx) { 1389 ctx.WriteString("stats_auto_recalc = ") 1390 if node.Default { 1391 ctx.WriteString("default") 1392 } else { 1393 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1394 } 1395 } 1396 1397 func NewTableOptionStatsAutoRecalc(v uint64, d bool) *TableOptionStatsAutoRecalc { 1398 return &TableOptionStatsAutoRecalc{ 1399 Value: v, 1400 Default: d, 1401 } 1402 } 1403 1404 type TableOptionPackKeys struct { 1405 tableOptionImpl 1406 Value int64 1407 Default bool 1408 } 1409 1410 func (node *TableOptionPackKeys) Format(ctx *FmtCtx) { 1411 ctx.WriteString("pack_keys = ") 1412 if node.Default { 1413 ctx.WriteString("default") 1414 } else { 1415 ctx.WriteString(strconv.FormatInt(node.Value, 10)) 1416 } 1417 } 1418 1419 func NewTableOptionPackKeys(value int64) *TableOptionPackKeys { 1420 return &TableOptionPackKeys{Value: value} 1421 } 1422 1423 type TableOptionTablespace struct { 1424 tableOptionImpl 1425 Name string 1426 StorageOpt string 1427 } 1428 1429 func (node *TableOptionTablespace) Format(ctx *FmtCtx) { 1430 ctx.WriteString("tablespace = ") 1431 ctx.WriteString(node.Name) 1432 ctx.WriteString(node.StorageOpt) 1433 } 1434 1435 func NewTableOptionTablespace(n string, s string) *TableOptionTablespace { 1436 return &TableOptionTablespace{Name: n, StorageOpt: s} 1437 } 1438 1439 type TableOptionDataDirectory struct { 1440 tableOptionImpl 1441 Dir string 1442 } 1443 1444 func (node *TableOptionDataDirectory) Format(ctx *FmtCtx) { 1445 ctx.WriteString("data directory = ") 1446 ctx.WriteString(node.Dir) 1447 } 1448 1449 func NewTableOptionDataDirectory(d string) *TableOptionDataDirectory { 1450 return &TableOptionDataDirectory{Dir: d} 1451 } 1452 1453 type TableOptionIndexDirectory struct { 1454 tableOptionImpl 1455 Dir string 1456 } 1457 1458 func (node *TableOptionIndexDirectory) Format(ctx *FmtCtx) { 1459 ctx.WriteString("index directory = ") 1460 ctx.WriteString(node.Dir) 1461 } 1462 1463 func NewTableOptionIndexDirectory(d string) *TableOptionIndexDirectory { 1464 return &TableOptionIndexDirectory{ 1465 Dir: d, 1466 } 1467 } 1468 1469 type TableOptionStorageMedia struct { 1470 tableOptionImpl 1471 Media string 1472 } 1473 1474 func (node *TableOptionStorageMedia) Format(ctx *FmtCtx) { 1475 ctx.WriteString("storage media = ") 1476 ctx.WriteString(node.Media) 1477 } 1478 1479 func NewTableOptionStorageMedia(m string) *TableOptionStorageMedia { 1480 return &TableOptionStorageMedia{Media: m} 1481 } 1482 1483 type TableOptionStatsSamplePages struct { 1484 tableOptionImpl 1485 Value uint64 1486 Default bool //false -- see Value; true -- Value is useless 1487 } 1488 1489 func (node *TableOptionStatsSamplePages) Format(ctx *FmtCtx) { 1490 ctx.WriteString("stats_sample_pages = ") 1491 if node.Default { 1492 ctx.WriteString("default") 1493 } else { 1494 ctx.WriteString(strconv.FormatUint(node.Value, 10)) 1495 } 1496 } 1497 1498 func NewTableOptionStatsSamplePages(v uint64, d bool) *TableOptionStatsSamplePages { 1499 return &TableOptionStatsSamplePages{ 1500 Value: v, 1501 Default: d, 1502 } 1503 } 1504 1505 type TableOptionUnion struct { 1506 tableOptionImpl 1507 Names TableNames 1508 } 1509 1510 func (node *TableOptionUnion) Format(ctx *FmtCtx) { 1511 ctx.WriteString("union (") 1512 node.Names.Format(ctx) 1513 ctx.WriteByte(')') 1514 } 1515 1516 func NewTableOptionUnion(n TableNames) *TableOptionUnion { 1517 return &TableOptionUnion{Names: n} 1518 } 1519 1520 type TableOptionEncryption struct { 1521 tableOptionImpl 1522 Encryption string 1523 } 1524 1525 func (node *TableOptionEncryption) Format(ctx *FmtCtx) { 1526 ctx.WriteString("encryption = ") 1527 ctx.WriteString(node.Encryption) 1528 } 1529 1530 func NewTableOptionEncryption(e string) *TableOptionEncryption { 1531 return &TableOptionEncryption{Encryption: e} 1532 } 1533 1534 type PartitionType interface { 1535 NodeFormatter 1536 } 1537 1538 type partitionTypeImpl struct { 1539 PartitionType 1540 } 1541 1542 type HashType struct { 1543 partitionTypeImpl 1544 Linear bool 1545 Expr Expr 1546 } 1547 1548 func (node *HashType) Format(ctx *FmtCtx) { 1549 if node.Linear { 1550 ctx.WriteString("linear ") 1551 } 1552 ctx.WriteString("hash") 1553 if node.Expr != nil { 1554 ctx.WriteString(" (") 1555 node.Expr.Format(ctx) 1556 ctx.WriteByte(')') 1557 } 1558 } 1559 1560 func NewHashType(l bool, e Expr) *HashType { 1561 return &HashType{ 1562 Linear: l, 1563 Expr: e, 1564 } 1565 } 1566 1567 type KeyType struct { 1568 partitionTypeImpl 1569 Linear bool 1570 ColumnList []*UnresolvedName 1571 Algorithm int64 1572 } 1573 1574 func (node *KeyType) Format(ctx *FmtCtx) { 1575 if node.Linear { 1576 ctx.WriteString("linear ") 1577 } 1578 ctx.WriteString("key") 1579 if node.Algorithm != 0 { 1580 ctx.WriteString(" algorithm = ") 1581 ctx.WriteString(strconv.FormatInt(node.Algorithm, 10)) 1582 } 1583 if node.ColumnList != nil { 1584 prefix := " (" 1585 for _, c := range node.ColumnList { 1586 ctx.WriteString(prefix) 1587 c.Format(ctx) 1588 prefix = ", " 1589 } 1590 ctx.WriteByte(')') 1591 } 1592 } 1593 1594 func NewKeyType(l bool, c []*UnresolvedName) *KeyType { 1595 return &KeyType{ 1596 Linear: l, 1597 ColumnList: c, 1598 } 1599 } 1600 1601 type RangeType struct { 1602 partitionTypeImpl 1603 Expr Expr 1604 ColumnList []*UnresolvedName 1605 } 1606 1607 func (node *RangeType) Format(ctx *FmtCtx) { 1608 ctx.WriteString("range") 1609 if node.ColumnList != nil { 1610 prefix := " columns (" 1611 for _, c := range node.ColumnList { 1612 ctx.WriteString(prefix) 1613 c.Format(ctx) 1614 prefix = ", " 1615 } 1616 ctx.WriteByte(')') 1617 } 1618 if node.Expr != nil { 1619 ctx.WriteString("(") 1620 node.Expr.Format(ctx) 1621 ctx.WriteByte(')') 1622 } 1623 } 1624 1625 func NewRangeType(e Expr, c []*UnresolvedName) *RangeType { 1626 return &RangeType{ 1627 Expr: e, 1628 ColumnList: c, 1629 } 1630 } 1631 1632 type ListType struct { 1633 partitionTypeImpl 1634 Expr Expr 1635 ColumnList []*UnresolvedName 1636 } 1637 1638 func (node *ListType) Format(ctx *FmtCtx) { 1639 ctx.WriteString("list") 1640 if node.ColumnList != nil { 1641 prefix := " columns (" 1642 for _, c := range node.ColumnList { 1643 ctx.WriteString(prefix) 1644 c.Format(ctx) 1645 prefix = ", " 1646 } 1647 ctx.WriteByte(')') 1648 } 1649 if node.Expr != nil { 1650 ctx.WriteString("(") 1651 node.Expr.Format(ctx) 1652 ctx.WriteByte(')') 1653 } 1654 } 1655 1656 func NewListType(e Expr, c []*UnresolvedName) *ListType { 1657 return &ListType{ 1658 Expr: e, 1659 ColumnList: c, 1660 } 1661 } 1662 1663 type PartitionBy struct { 1664 IsSubPartition bool // for format 1665 PType PartitionType 1666 Num uint64 1667 } 1668 1669 func (node *PartitionBy) Format(ctx *FmtCtx) { 1670 node.PType.Format(ctx) 1671 if node.Num != 0 { 1672 if node.IsSubPartition { 1673 ctx.WriteString(" subpartitions ") 1674 } else { 1675 ctx.WriteString(" partitions ") 1676 } 1677 ctx.WriteString(strconv.FormatUint(node.Num, 10)) 1678 } 1679 } 1680 1681 func NewPartitionBy(pt PartitionType, n uint64) *PartitionBy { 1682 return &PartitionBy{ 1683 PType: pt, 1684 Num: n, 1685 } 1686 } 1687 1688 //type SubpartitionBy struct { 1689 // SubPType PartitionType 1690 // Num uint64 1691 //} 1692 1693 type Values interface { 1694 NodeFormatter 1695 } 1696 1697 type valuesImpl struct { 1698 Values 1699 } 1700 1701 type ValuesLessThan struct { 1702 valuesImpl 1703 ValueList Exprs 1704 } 1705 1706 func (node *ValuesLessThan) Format(ctx *FmtCtx) { 1707 ctx.WriteString("values less than (") 1708 node.ValueList.Format(ctx) 1709 ctx.WriteByte(')') 1710 } 1711 1712 func NewValuesLessThan(vl Exprs) *ValuesLessThan { 1713 return &ValuesLessThan{ 1714 ValueList: vl, 1715 } 1716 } 1717 1718 type ValuesIn struct { 1719 valuesImpl 1720 ValueList Exprs 1721 } 1722 1723 func (node *ValuesIn) Format(ctx *FmtCtx) { 1724 ctx.WriteString("values in (") 1725 node.ValueList.Format(ctx) 1726 ctx.WriteByte(')') 1727 } 1728 1729 func NewValuesIn(vl Exprs) *ValuesIn { 1730 return &ValuesIn{ 1731 ValueList: vl, 1732 } 1733 } 1734 1735 type Partition struct { 1736 Name Identifier 1737 Values Values 1738 Options []TableOption 1739 Subs []*SubPartition 1740 } 1741 1742 func (node *Partition) Format(ctx *FmtCtx) { 1743 ctx.WriteString("partition ") 1744 ctx.WriteString(string(node.Name)) 1745 if node.Values != nil { 1746 ctx.WriteByte(' ') 1747 node.Values.Format(ctx) 1748 } 1749 if node.Options != nil { 1750 prefix := " " 1751 for _, t := range node.Options { 1752 ctx.WriteString(prefix) 1753 t.Format(ctx) 1754 prefix = " " 1755 } 1756 } 1757 if node.Subs != nil { 1758 prefix := " (" 1759 for _, s := range node.Subs { 1760 ctx.WriteString(prefix) 1761 s.Format(ctx) 1762 prefix = ", " 1763 } 1764 ctx.WriteByte(')') 1765 } 1766 } 1767 1768 func NewPartition(n Identifier, v Values, o []TableOption, s []*SubPartition) *Partition { 1769 return &Partition{ 1770 Name: n, 1771 Values: v, 1772 Options: o, 1773 Subs: s, 1774 } 1775 } 1776 1777 type SubPartition struct { 1778 Name Identifier 1779 Options []TableOption 1780 } 1781 1782 func (node *SubPartition) Format(ctx *FmtCtx) { 1783 ctx.WriteString("subpartition ") 1784 ctx.WriteString(string(node.Name)) 1785 1786 if node.Options != nil { 1787 prefix := " " 1788 for _, t := range node.Options { 1789 ctx.WriteString(prefix) 1790 t.Format(ctx) 1791 prefix = " " 1792 } 1793 } 1794 } 1795 1796 func NewSubPartition(n Identifier, o []TableOption) *SubPartition { 1797 return &SubPartition{ 1798 Name: n, 1799 Options: o, 1800 } 1801 } 1802 1803 type ClusterByOption struct { 1804 ColumnList []*UnresolvedName 1805 } 1806 1807 type PartitionOption struct { 1808 PartBy PartitionBy 1809 SubPartBy *PartitionBy 1810 Partitions []*Partition 1811 } 1812 1813 func (node *PartitionOption) Format(ctx *FmtCtx) { 1814 ctx.WriteString("partition by ") 1815 node.PartBy.Format(ctx) 1816 if node.SubPartBy != nil { 1817 ctx.WriteString(" subpartition by ") 1818 node.SubPartBy.Format(ctx) 1819 } 1820 if node.Partitions != nil { 1821 prefix := " (" 1822 for _, p := range node.Partitions { 1823 ctx.WriteString(prefix) 1824 p.Format(ctx) 1825 prefix = ", " 1826 } 1827 ctx.WriteByte(')') 1828 } 1829 } 1830 1831 func NewPartitionOption(pb *PartitionBy, spb *PartitionBy, parts []*Partition) *PartitionOption { 1832 return &PartitionOption{ 1833 PartBy: *pb, 1834 SubPartBy: spb, 1835 Partitions: parts, 1836 } 1837 } 1838 1839 type IndexCategory int 1840 1841 func (ic IndexCategory) ToString() string { 1842 switch ic { 1843 case INDEX_CATEGORY_UNIQUE: 1844 return "unique" 1845 case INDEX_CATEGORY_FULLTEXT: 1846 return "fulltext" 1847 case INDEX_CATEGORY_SPATIAL: 1848 return "spatial" 1849 default: 1850 return "Unknown IndexCategory" 1851 } 1852 } 1853 1854 const ( 1855 INDEX_CATEGORY_NONE IndexCategory = iota 1856 INDEX_CATEGORY_UNIQUE 1857 INDEX_CATEGORY_FULLTEXT 1858 INDEX_CATEGORY_SPATIAL 1859 ) 1860 1861 type CreateIndex struct { 1862 statementImpl 1863 Name Identifier 1864 Table TableName 1865 IndexCat IndexCategory 1866 IfNotExists bool 1867 KeyParts []*KeyPart 1868 IndexOption *IndexOption 1869 MiscOption []MiscOption 1870 } 1871 1872 func (node *CreateIndex) Format(ctx *FmtCtx) { 1873 ctx.WriteString("create ") 1874 if node.IndexCat != INDEX_CATEGORY_NONE { 1875 ctx.WriteString(node.IndexCat.ToString()) 1876 ctx.WriteByte(' ') 1877 } 1878 1879 ctx.WriteString("index ") 1880 node.Name.Format(ctx) 1881 ctx.WriteByte(' ') 1882 1883 if node.IndexOption != nil && node.IndexOption.IType != INDEX_TYPE_INVALID { 1884 ctx.WriteString("using ") 1885 ctx.WriteString(node.IndexOption.IType.ToString()) 1886 ctx.WriteByte(' ') 1887 } 1888 1889 ctx.WriteString("on ") 1890 node.Table.Format(ctx) 1891 1892 ctx.WriteString(" (") 1893 if node.KeyParts != nil { 1894 prefix := "" 1895 for _, kp := range node.KeyParts { 1896 ctx.WriteString(prefix) 1897 kp.Format(ctx) 1898 prefix = ", " 1899 } 1900 } 1901 ctx.WriteString(")") 1902 if node.IndexOption != nil { 1903 ctx.WriteByte(' ') 1904 node.IndexOption.Format(ctx) 1905 } 1906 } 1907 1908 func (node *CreateIndex) GetStatementType() string { return "Create Index" } 1909 func (node *CreateIndex) GetQueryType() string { return QueryTypeDDL } 1910 1911 func NewCreateIndex(n Identifier, t TableName, ife bool, it IndexCategory, k []*KeyPart, i *IndexOption, m []MiscOption) *CreateIndex { 1912 return &CreateIndex{ 1913 Name: n, 1914 Table: t, 1915 IfNotExists: ife, 1916 IndexCat: it, 1917 KeyParts: k, 1918 IndexOption: i, 1919 MiscOption: m, 1920 } 1921 } 1922 1923 type MiscOption interface { 1924 NodeFormatter 1925 } 1926 1927 type miscOption struct { 1928 MiscOption 1929 } 1930 1931 type AlgorithmDefault struct { 1932 miscOption 1933 } 1934 1935 type AlgorithmInplace struct { 1936 miscOption 1937 } 1938 1939 type AlgorithmCopy struct { 1940 miscOption 1941 } 1942 1943 type LockDefault struct { 1944 miscOption 1945 } 1946 1947 type LockNone struct { 1948 miscOption 1949 } 1950 1951 type LockShared struct { 1952 miscOption 1953 } 1954 1955 type LockExclusive struct { 1956 miscOption 1957 } 1958 1959 type CreateRole struct { 1960 statementImpl 1961 IfNotExists bool 1962 Roles []*Role 1963 } 1964 1965 func (node *CreateRole) Format(ctx *FmtCtx) { 1966 ctx.WriteString("create role ") 1967 if node.IfNotExists { 1968 ctx.WriteString("if not exists ") 1969 } 1970 prefix := "" 1971 for _, r := range node.Roles { 1972 ctx.WriteString(prefix) 1973 r.Format(ctx) 1974 prefix = ", " 1975 } 1976 } 1977 1978 func (node *CreateRole) GetStatementType() string { return "Create Role" } 1979 func (node *CreateRole) GetQueryType() string { return QueryTypeDCL } 1980 1981 func NewCreateRole(ife bool, r []*Role) *CreateRole { 1982 return &CreateRole{ 1983 IfNotExists: ife, 1984 Roles: r, 1985 } 1986 } 1987 1988 type Role struct { 1989 NodeFormatter 1990 UserName string 1991 } 1992 1993 func (node *Role) Format(ctx *FmtCtx) { 1994 ctx.WriteString(node.UserName) 1995 } 1996 1997 func NewRole(u string) *Role { 1998 return &Role{ 1999 UserName: u, 2000 } 2001 } 2002 2003 type User struct { 2004 NodeFormatter 2005 Username string 2006 Hostname string 2007 AuthOption *AccountIdentified 2008 } 2009 2010 func (node *User) Format(ctx *FmtCtx) { 2011 ctx.WriteString(node.Username) 2012 if node.Hostname != "%" { 2013 ctx.WriteByte('@') 2014 ctx.WriteString(node.Hostname) 2015 } 2016 if node.AuthOption != nil { 2017 node.AuthOption.Format(ctx) 2018 } 2019 } 2020 2021 func NewUser(u, h string) *User { 2022 return &User{ 2023 Username: u, 2024 Hostname: h, 2025 } 2026 } 2027 2028 type UsernameRecord struct { 2029 Username string 2030 Hostname string 2031 } 2032 2033 type AuthRecord struct { 2034 AuthPlugin string 2035 AuthString string 2036 HashString string 2037 ByAuth bool 2038 } 2039 2040 type TlsOption interface { 2041 NodeFormatter 2042 } 2043 2044 type tlsOptionImpl struct { 2045 TlsOption 2046 } 2047 2048 type TlsOptionNone struct { 2049 tlsOptionImpl 2050 } 2051 2052 func (node *TlsOptionNone) Format(ctx *FmtCtx) { 2053 ctx.WriteString("none") 2054 } 2055 2056 type TlsOptionSSL struct { 2057 tlsOptionImpl 2058 } 2059 2060 func (node *TlsOptionSSL) Format(ctx *FmtCtx) { 2061 ctx.WriteString("ssl") 2062 } 2063 2064 type TlsOptionX509 struct { 2065 tlsOptionImpl 2066 } 2067 2068 func (node *TlsOptionX509) Format(ctx *FmtCtx) { 2069 ctx.WriteString("x509") 2070 } 2071 2072 type TlsOptionCipher struct { 2073 tlsOptionImpl 2074 Cipher string 2075 } 2076 2077 func (node *TlsOptionCipher) Format(ctx *FmtCtx) { 2078 ctx.WriteString("cipher ") 2079 ctx.WriteString(node.Cipher) 2080 } 2081 2082 type TlsOptionIssuer struct { 2083 tlsOptionImpl 2084 Issuer string 2085 } 2086 2087 func (node *TlsOptionIssuer) Format(ctx *FmtCtx) { 2088 ctx.WriteString("issuer ") 2089 ctx.WriteString(node.Issuer) 2090 } 2091 2092 type TlsOptionSubject struct { 2093 tlsOptionImpl 2094 Subject string 2095 } 2096 2097 func (node *TlsOptionSubject) Format(ctx *FmtCtx) { 2098 ctx.WriteString("subject ") 2099 ctx.WriteString(node.Subject) 2100 } 2101 2102 type TlsOptionSan struct { 2103 tlsOptionImpl 2104 San string 2105 } 2106 2107 func (node *TlsOptionSan) Format(ctx *FmtCtx) { 2108 ctx.WriteString("san ") 2109 ctx.WriteString(node.San) 2110 } 2111 2112 type ResourceOption interface { 2113 NodeFormatter 2114 } 2115 2116 type resourceOptionImpl struct { 2117 ResourceOption 2118 } 2119 2120 type ResourceOptionMaxQueriesPerHour struct { 2121 resourceOptionImpl 2122 Count int64 2123 } 2124 2125 func (node *ResourceOptionMaxQueriesPerHour) Format(ctx *FmtCtx) { 2126 ctx.WriteString("max_queries_per_hour ") 2127 ctx.WriteString(strconv.FormatInt(node.Count, 10)) 2128 } 2129 2130 type ResourceOptionMaxUpdatesPerHour struct { 2131 resourceOptionImpl 2132 Count int64 2133 } 2134 2135 func (node *ResourceOptionMaxUpdatesPerHour) Format(ctx *FmtCtx) { 2136 ctx.WriteString("max_updates_per_hour ") 2137 ctx.WriteString(strconv.FormatInt(node.Count, 10)) 2138 } 2139 2140 type ResourceOptionMaxConnectionPerHour struct { 2141 resourceOptionImpl 2142 Count int64 2143 } 2144 2145 func (node *ResourceOptionMaxConnectionPerHour) Format(ctx *FmtCtx) { 2146 ctx.WriteString("max_connections_per_hour ") 2147 ctx.WriteString(strconv.FormatInt(node.Count, 10)) 2148 } 2149 2150 type ResourceOptionMaxUserConnections struct { 2151 resourceOptionImpl 2152 Count int64 2153 } 2154 2155 func (node *ResourceOptionMaxUserConnections) Format(ctx *FmtCtx) { 2156 ctx.WriteString("max_user_connections ") 2157 ctx.WriteString(strconv.FormatInt(node.Count, 10)) 2158 } 2159 2160 type UserMiscOption interface { 2161 NodeFormatter 2162 } 2163 2164 type userMiscOptionImpl struct { 2165 UserMiscOption 2166 } 2167 2168 type UserMiscOptionPasswordExpireNone struct { 2169 userMiscOptionImpl 2170 } 2171 2172 func (node *UserMiscOptionPasswordExpireNone) Format(ctx *FmtCtx) { 2173 ctx.WriteString("password expire") 2174 } 2175 2176 type UserMiscOptionPasswordExpireDefault struct { 2177 userMiscOptionImpl 2178 } 2179 2180 func (node *UserMiscOptionPasswordExpireDefault) Format(ctx *FmtCtx) { 2181 ctx.WriteString("password expire default") 2182 } 2183 2184 type UserMiscOptionPasswordExpireNever struct { 2185 userMiscOptionImpl 2186 } 2187 2188 func (node *UserMiscOptionPasswordExpireNever) Format(ctx *FmtCtx) { 2189 ctx.WriteString("password expire never") 2190 } 2191 2192 type UserMiscOptionPasswordExpireInterval struct { 2193 userMiscOptionImpl 2194 Value int64 2195 } 2196 2197 func (node *UserMiscOptionPasswordExpireInterval) Format(ctx *FmtCtx) { 2198 ctx.WriteString("password expire interval ") 2199 ctx.WriteString(strconv.FormatInt(node.Value, 10)) 2200 ctx.WriteString(" day") 2201 } 2202 2203 type UserMiscOptionPasswordHistoryDefault struct { 2204 userMiscOptionImpl 2205 } 2206 2207 func (node *UserMiscOptionPasswordHistoryDefault) Format(ctx *FmtCtx) { 2208 ctx.WriteString("password history default") 2209 } 2210 2211 type UserMiscOptionPasswordHistoryCount struct { 2212 userMiscOptionImpl 2213 Value int64 2214 } 2215 2216 func (node *UserMiscOptionPasswordHistoryCount) Format(ctx *FmtCtx) { 2217 ctx.WriteString(fmt.Sprintf("password history %d", node.Value)) 2218 } 2219 2220 type UserMiscOptionPasswordReuseIntervalDefault struct { 2221 userMiscOptionImpl 2222 } 2223 2224 func (node *UserMiscOptionPasswordReuseIntervalDefault) Format(ctx *FmtCtx) { 2225 ctx.WriteString("password reuse interval default") 2226 } 2227 2228 type UserMiscOptionPasswordReuseIntervalCount struct { 2229 userMiscOptionImpl 2230 Value int64 2231 } 2232 2233 func (node *UserMiscOptionPasswordReuseIntervalCount) Format(ctx *FmtCtx) { 2234 ctx.WriteString(fmt.Sprintf("password reuse interval %d day", node.Value)) 2235 } 2236 2237 type UserMiscOptionPasswordRequireCurrentNone struct { 2238 userMiscOptionImpl 2239 } 2240 2241 func (node *UserMiscOptionPasswordRequireCurrentNone) Format(ctx *FmtCtx) { 2242 ctx.WriteString("password require current") 2243 } 2244 2245 type UserMiscOptionPasswordRequireCurrentDefault struct { 2246 userMiscOptionImpl 2247 } 2248 2249 func (node *UserMiscOptionPasswordRequireCurrentDefault) Format(ctx *FmtCtx) { 2250 ctx.WriteString("password require current default") 2251 } 2252 2253 type UserMiscOptionPasswordRequireCurrentOptional struct { 2254 userMiscOptionImpl 2255 } 2256 2257 func (node *UserMiscOptionPasswordRequireCurrentOptional) Format(ctx *FmtCtx) { 2258 ctx.WriteString("password require current optional") 2259 } 2260 2261 type UserMiscOptionFailedLoginAttempts struct { 2262 userMiscOptionImpl 2263 Value int64 2264 } 2265 2266 func (node *UserMiscOptionFailedLoginAttempts) Format(ctx *FmtCtx) { 2267 ctx.WriteString(fmt.Sprintf("failed_login_attempts %d", node.Value)) 2268 } 2269 2270 type UserMiscOptionPasswordLockTimeCount struct { 2271 userMiscOptionImpl 2272 Value int64 2273 } 2274 2275 func (node *UserMiscOptionPasswordLockTimeCount) Format(ctx *FmtCtx) { 2276 ctx.WriteString(fmt.Sprintf("password_lock_time %d", node.Value)) 2277 } 2278 2279 type UserMiscOptionPasswordLockTimeUnbounded struct { 2280 userMiscOptionImpl 2281 } 2282 2283 func (node *UserMiscOptionPasswordLockTimeUnbounded) Format(ctx *FmtCtx) { 2284 ctx.WriteString("password_lock_time unbounded") 2285 } 2286 2287 type UserMiscOptionAccountLock struct { 2288 userMiscOptionImpl 2289 } 2290 2291 func (node *UserMiscOptionAccountLock) Format(ctx *FmtCtx) { 2292 ctx.WriteString("lock") 2293 } 2294 2295 type UserMiscOptionAccountUnlock struct { 2296 userMiscOptionImpl 2297 } 2298 2299 func (node *UserMiscOptionAccountUnlock) Format(ctx *FmtCtx) { 2300 ctx.WriteString("unlock") 2301 } 2302 2303 type CreateUser struct { 2304 statementImpl 2305 IfNotExists bool 2306 Users []*User 2307 Role *Role 2308 MiscOpt UserMiscOption 2309 // comment or attribute 2310 CommentOrAttribute AccountCommentOrAttribute 2311 } 2312 2313 func (node *CreateUser) Format(ctx *FmtCtx) { 2314 ctx.WriteString("create user ") 2315 if node.IfNotExists { 2316 ctx.WriteString("if not exists ") 2317 } 2318 if node.Users != nil { 2319 prefix := "" 2320 for _, u := range node.Users { 2321 ctx.WriteString(prefix) 2322 u.Format(ctx) 2323 prefix = ", " 2324 } 2325 } 2326 2327 if node.Role != nil { 2328 ctx.WriteString(" default role") 2329 ctx.WriteString(" ") 2330 node.Role.Format(ctx) 2331 } 2332 2333 if node.MiscOpt != nil { 2334 ctx.WriteString(" ") 2335 node.MiscOpt.Format(ctx) 2336 } 2337 2338 node.CommentOrAttribute.Format(ctx) 2339 } 2340 2341 func (node *CreateUser) GetStatementType() string { return "Create User" } 2342 func (node *CreateUser) GetQueryType() string { return QueryTypeDCL } 2343 2344 func NewCreateUser(ife bool, u []*User, r *Role, misc UserMiscOption) *CreateUser { 2345 return &CreateUser{ 2346 IfNotExists: ife, 2347 Users: u, 2348 Role: r, 2349 MiscOpt: misc, 2350 } 2351 } 2352 2353 type CreateAccount struct { 2354 statementImpl 2355 IfNotExists bool 2356 Name string 2357 AuthOption AccountAuthOption 2358 //status_option or not 2359 StatusOption AccountStatus 2360 //comment or not 2361 Comment AccountComment 2362 } 2363 2364 func (ca *CreateAccount) Format(ctx *FmtCtx) { 2365 ctx.WriteString("create account ") 2366 if ca.IfNotExists { 2367 ctx.WriteString("if not exists ") 2368 } 2369 ctx.WriteString(ca.Name) 2370 ca.AuthOption.Format(ctx) 2371 ca.StatusOption.Format(ctx) 2372 ca.Comment.Format(ctx) 2373 } 2374 2375 func (ca *CreateAccount) GetStatementType() string { return "Create Account" } 2376 func (ca *CreateAccount) GetQueryType() string { return QueryTypeDCL } 2377 2378 type AccountAuthOption struct { 2379 Equal string 2380 AdminName string 2381 IdentifiedType AccountIdentified 2382 } 2383 2384 func (node *AccountAuthOption) Format(ctx *FmtCtx) { 2385 ctx.WriteString(" admin_name") 2386 if len(node.Equal) != 0 { 2387 ctx.WriteString(" ") 2388 ctx.WriteString(node.Equal) 2389 } 2390 2391 ctx.WriteString(fmt.Sprintf(" '%s'", node.AdminName)) 2392 node.IdentifiedType.Format(ctx) 2393 2394 } 2395 2396 type AccountIdentifiedOption int 2397 2398 const ( 2399 AccountIdentifiedByPassword AccountIdentifiedOption = iota 2400 AccountIdentifiedByRandomPassword 2401 AccountIdentifiedWithSSL 2402 ) 2403 2404 type AccountIdentified struct { 2405 Typ AccountIdentifiedOption 2406 Str string 2407 } 2408 2409 func (node *AccountIdentified) Format(ctx *FmtCtx) { 2410 switch node.Typ { 2411 case AccountIdentifiedByPassword: 2412 ctx.WriteString(fmt.Sprintf(" identified by '%s'", node.Str)) 2413 case AccountIdentifiedByRandomPassword: 2414 ctx.WriteString(" identified by random password") 2415 case AccountIdentifiedWithSSL: 2416 ctx.WriteString(fmt.Sprintf(" identified with '%s'", node.Str)) 2417 } 2418 } 2419 2420 type AccountStatusOption int 2421 2422 const ( 2423 AccountStatusOpen AccountStatusOption = iota 2424 AccountStatusSuspend 2425 ) 2426 2427 func (aso AccountStatusOption) String() string { 2428 switch aso { 2429 case AccountStatusOpen: 2430 return "open" 2431 case AccountStatusSuspend: 2432 return "suspend" 2433 default: 2434 return "open" 2435 } 2436 } 2437 2438 type AccountStatus struct { 2439 Exist bool 2440 Option AccountStatusOption 2441 } 2442 2443 func (node *AccountStatus) Format(ctx *FmtCtx) { 2444 if node.Exist { 2445 switch node.Option { 2446 case AccountStatusOpen: 2447 ctx.WriteString(" open") 2448 case AccountStatusSuspend: 2449 ctx.WriteString(" suspend") 2450 } 2451 } 2452 } 2453 2454 type AccountComment struct { 2455 Exist bool 2456 Comment string 2457 } 2458 2459 func (node *AccountComment) Format(ctx *FmtCtx) { 2460 if node.Exist { 2461 ctx.WriteString(" comment ") 2462 ctx.WriteString(fmt.Sprintf("'%s'", node.Comment)) 2463 } 2464 } 2465 2466 type AccountCommentOrAttribute struct { 2467 Exist bool 2468 IsComment bool 2469 Str string 2470 } 2471 2472 func (node *AccountCommentOrAttribute) Format(ctx *FmtCtx) { 2473 if node.Exist { 2474 if node.IsComment { 2475 ctx.WriteString(" comment ") 2476 } else { 2477 ctx.WriteString(" attribute ") 2478 } 2479 ctx.WriteString(fmt.Sprintf("'%s'", node.Str)) 2480 } 2481 }