1# -*- coding: utf-8 -*- 2# :Project: pglast -- Printer function for SQL DDL nodes 3# :Created: gio 09 nov 2017 10:50:30 CET 4# :Author: Lele Gaifax <lele@metapensiero.it> 5# :License: GNU General Public License version 3 or later 6# :Copyright: © 2017, 2018 Lele Gaifax 7# 8 9from .. import enums 10from ..node import Missing, List 11from ..printer import node_printer 12 13 14@node_printer('ColumnDef') 15def column_def(node, output): 16 output.print_name(node.colname) 17 output.space() 18 if node.typeName: 19 output.print_name(node.typeName) 20 else: 21 if node.constraints: 22 output.write('WITH OPTIONS ') 23 if node.collClause: 24 output.print_node(node.collClause) 25 if node.is_not_null: 26 # FIXME: find a way to get here 27 output.swrite('NOT NULL') 28 if node.constraints: 29 output.print_list(node.constraints, '', standalone_items=False) 30 31 32OBJECT_NAMES = { 33 enums.ObjectType.OBJECT_ACCESS_METHOD: 'ACCESS METHOD', 34 enums.ObjectType.OBJECT_AGGREGATE: 'AGGREGATE', 35 enums.ObjectType.OBJECT_AMOP: 'AMOP', 36 enums.ObjectType.OBJECT_AMPROC: 'AMPROC', 37 enums.ObjectType.OBJECT_ATTRIBUTE: 'ATTRIBUTE', 38 enums.ObjectType.OBJECT_CAST: 'CAST', 39 enums.ObjectType.OBJECT_COLUMN: 'COLUMN', 40 enums.ObjectType.OBJECT_COLLATION: 'COLLATION', 41 enums.ObjectType.OBJECT_CONVERSION: 'CONVERSION', 42 enums.ObjectType.OBJECT_DATABASE: 'DATABASE', 43 enums.ObjectType.OBJECT_DEFAULT: 'DEFAULT', 44 enums.ObjectType.OBJECT_DEFACL: 'DEFACL', 45 enums.ObjectType.OBJECT_DOMAIN: 'DOMAIN', 46 enums.ObjectType.OBJECT_DOMCONSTRAINT: 'CONSTRAINT', 47 enums.ObjectType.OBJECT_EVENT_TRIGGER: 'EVENT TRIGGER', 48 enums.ObjectType.OBJECT_EXTENSION: 'EXTENSION', 49 enums.ObjectType.OBJECT_FDW: 'FOREIGN DATA WRAPPER', 50 enums.ObjectType.OBJECT_FOREIGN_SERVER: 'SERVER', 51 enums.ObjectType.OBJECT_FOREIGN_TABLE: 'FOREIGN TABLE', 52 enums.ObjectType.OBJECT_FUNCTION: 'FUNCTION', 53 enums.ObjectType.OBJECT_INDEX: 'INDEX', 54 enums.ObjectType.OBJECT_LANGUAGE: 'LANGUAGE', 55 enums.ObjectType.OBJECT_LARGEOBJECT: 'LARGE OBJECT', 56 enums.ObjectType.OBJECT_MATVIEW: 'MATERIALIZED VIEW', 57 enums.ObjectType.OBJECT_OPCLASS: 'OPERATOR CLASS', 58 enums.ObjectType.OBJECT_OPERATOR: 'OPERATOR', 59 enums.ObjectType.OBJECT_OPFAMILY: 'OPERATOR FAMILY', 60 enums.ObjectType.OBJECT_POLICY: 'POLICY', 61 enums.ObjectType.OBJECT_PUBLICATION: 'PUBLICATION', 62 enums.ObjectType.OBJECT_PUBLICATION_REL: 'PUBLICATION_REL', 63 enums.ObjectType.OBJECT_ROLE: 'ROLE', 64 enums.ObjectType.OBJECT_RULE: 'RULE', 65 enums.ObjectType.OBJECT_SCHEMA: 'SCHEMA', 66 enums.ObjectType.OBJECT_SEQUENCE: 'SEQUENCE', 67 enums.ObjectType.OBJECT_SUBSCRIPTION: 'SUBSCRIPTION', 68 enums.ObjectType.OBJECT_STATISTIC_EXT: 'STATISTICS', 69 enums.ObjectType.OBJECT_TABCONSTRAINT: 'CONSTRAINT', 70 enums.ObjectType.OBJECT_TABLE: 'TABLE', 71 enums.ObjectType.OBJECT_TABLESPACE: 'TABLESPACE', 72 enums.ObjectType.OBJECT_TRANSFORM: 'TRANSFORM', 73 enums.ObjectType.OBJECT_TRIGGER: 'TRIGGER', 74 enums.ObjectType.OBJECT_TSCONFIGURATION: 'TEXT SEARCH CONFIGURATION', 75 enums.ObjectType.OBJECT_TSDICTIONARY: 'TEXT SEARCH DICTIONARY', 76 enums.ObjectType.OBJECT_TSPARSER: 'TEXT SEARCH PARSER', 77 enums.ObjectType.OBJECT_TSTEMPLATE: 'TEXT SEARCH TEMPLATE', 78 enums.ObjectType.OBJECT_TYPE: 'TYPE', 79 enums.ObjectType.OBJECT_USER_MAPPING: 'USER_MAPPING', 80 enums.ObjectType.OBJECT_VIEW: 'VIEW', 81} 82 83 84@node_printer('CommentStmt') 85def comment_stmt(node, output): 86 otypes = enums.ObjectType 87 output.write('COMMENT ') 88 output.write('ON ') 89 output.writes(OBJECT_NAMES[node.objtype.value]) 90 if node.objtype in (otypes.OBJECT_OPCLASS, otypes.OBJECT_OPFAMILY): 91 nodes = list(node.object) 92 using = nodes.pop(0) 93 output.print_name(nodes) 94 output.write(' USING ') 95 output.print_name(using) 96 elif node.objtype in (otypes.OBJECT_TABCONSTRAINT, otypes.OBJECT_POLICY, 97 otypes.OBJECT_RULE, otypes.OBJECT_TRIGGER): 98 nodes = list(node.object) 99 output.print_name(nodes.pop()) 100 output.write(' ON ') 101 output.print_name(nodes) 102 elif node.objtype == otypes.OBJECT_DOMCONSTRAINT: 103 nodes = list(node.object) 104 output.print_name(nodes.pop()) 105 output.write(' ON DOMAIN ') 106 output.print_name(nodes) 107 elif node.objtype == otypes.OBJECT_TRANSFORM: 108 nodes = list(node.object) 109 output.write('FOR ') 110 output.print_name(nodes.pop(0)) 111 output.write(' LANGUAGE ') 112 output.print_name(nodes) 113 elif isinstance(node.object, List): 114 if node.object[0].node_tag != 'String': 115 output.write(' (') 116 output.print_list(node.object, ' AS ', standalone_items=False) 117 output.write(')') 118 else: 119 output.print_name(node.object) 120 else: 121 output.print_name(node.object) 122 output.newline() 123 output.space(2) 124 output.write('IS ') 125 with output.push_indent(): 126 output._write_quoted_string(node.comment.value) 127 128 129@node_printer('Constraint') 130def constraint(node, output): 131 if node.conname: 132 output.swrite('CONSTRAINT ') 133 output.print_name(node.conname) 134 ct = enums.ConstrType 135 if node.contype == ct.CONSTR_NULL: 136 output.swrite('NULL') 137 elif node.contype == ct.CONSTR_DEFAULT: 138 output.swrite('DEFAULT ') 139 # """ 140 # we may have the expression in either "raw" form [...] or "cooked" form [...] 141 # should never have both in the same node! 142 # """ 143 output.print_node(node.raw_expr or node.cooked_expr) 144 elif node.contype == ct.CONSTR_NOTNULL: 145 output.swrite('NOT NULL') 146 elif node.contype == ct.CONSTR_CHECK: 147 output.swrite('CHECK (') 148 output.print_node(node.raw_expr or node.cooked_expr) 149 output.write(')') 150 if node.is_no_inherit: 151 output.swrite('NO INHERIT') 152 elif node.contype == ct.CONSTR_PRIMARY: 153 output.swrite('PRIMARY KEY') 154 elif node.contype == ct.CONSTR_UNIQUE: 155 output.swrite('UNIQUE') 156 elif node.contype == ct.CONSTR_EXCLUSION: 157 output.swrite('EXCLUDE USING ') 158 if node.access_method: 159 output.print_node(node.access_method) 160 output.write(' ') 161 output.write('(') 162 first = True 163 for elem, clauses in node.exclusions: 164 if first: 165 first = False 166 else: 167 output.write(', ') 168 output.print_node(elem) 169 output.swrite('WITH ') 170 output.write(clauses.string_value) 171 output.write(')') 172 elif node.contype == ct.CONSTR_FOREIGN: 173 if node.fk_attrs: 174 output.swrite('FOREIGN KEY ') 175 output.write(' (') 176 output.print_name(node.fk_attrs, ',') 177 output.write(')') 178 output.swrite('REFERENCES ') 179 output.print_name(node.pktable) 180 output.write(' (') 181 output.print_name(node.pk_attrs, ',') 182 output.write(')') 183 if node.fk_matchtype != enums.FKCONSTR_MATCH_SIMPLE: 184 output.write(' MATCH ') 185 if node.fk_matchtype == enums.FKCONSTR_MATCH_FULL: 186 output.write('FULL') 187 elif node.fk_matchtype == enums.FKCONSTR_MATCH_PARTIAL: # pragma: no cover 188 # MATCH PARTIAL not yet implemented 189 output.write('PARTIAL') 190 if node.fk_del_action != enums.FKCONSTR_ACTION_NOACTION: 191 output.write(' ON DELETE ') 192 if node.fk_del_action == enums.FKCONSTR_ACTION_RESTRICT: 193 output.write('RESTRICT') 194 elif node.fk_del_action == enums.FKCONSTR_ACTION_CASCADE: 195 output.write('CASCADE') 196 elif node.fk_del_action == enums.FKCONSTR_ACTION_SETNULL: 197 output.write('SET NULL') 198 elif node.fk_del_action == enums.FKCONSTR_ACTION_SETDEFAULT: 199 output.write('SET DEFAULT') 200 if node.fk_upd_action != enums.FKCONSTR_ACTION_NOACTION: 201 output.write(' ON UPDATE ') 202 if node.fk_upd_action == enums.FKCONSTR_ACTION_RESTRICT: 203 output.write('RESTRICT') 204 elif node.fk_upd_action == enums.FKCONSTR_ACTION_CASCADE: 205 output.write('CASCADE') 206 elif node.fk_upd_action == enums.FKCONSTR_ACTION_SETNULL: 207 output.write('SET NULL') 208 elif node.fk_upd_action == enums.FKCONSTR_ACTION_SETDEFAULT: 209 output.write('SET DEFAULT') 210 211 # Common to UNIQUE & PRIMARY_KEY 212 if node.keys: 213 output.write(' (') 214 output.print_name(node.keys, ',') 215 output.write(')') 216 with output.push_indent(): 217 first = True 218 if node.options: 219 output.write(' WITH (') 220 output.print_list(node.options) 221 output.write(')') 222 first = False 223 if node.indexspace: 224 if first: 225 first = False 226 else: 227 output.newline() 228 output.write(' USING INDEX TABLESPACE ') 229 output.print_name(node.indexspace) 230 231 232@node_printer('CreateAmStmt') 233def create_am_stmt(node, output): 234 output.write('CREATE ACCESS METHOD ') 235 output.print_name(node.amname) 236 if node.amtype == 'i': 237 output.write(' TYPE INDEX HANDLER ') 238 output.print_name(node.handler_name) 239 else: # pragma: nocover 240 raise NotImplementedError 241 242 243@node_printer('CreateCastStmt') 244def create_cast_stmt(node, output): 245 output.write('CREATE CAST (') 246 output.print_node(node.sourcetype) 247 output.write(' AS ') 248 output.print_node(node.targettype) 249 output.write(') ') 250 if node.func: 251 output.write('WITH FUNCTION ') 252 output.print_node(node.func) 253 elif node.inout: 254 output.write('WITH INOUT') 255 else: 256 output.write('WITHOUT FUNCTION') 257 if node.context == enums.CoercionContext.COERCION_ASSIGNMENT: 258 output.write(' AS ASSIGNMENT') 259 elif node.context == enums.CoercionContext.COERCION_IMPLICIT: 260 output.write(' AS IMPLICIT') 261 262 263@node_printer('CreateConversionStmt') 264def create_conversion_stmt(node, output): 265 output.write('CREATE ') 266 if node['def']: 267 output.write('DEFAULT ') 268 output.write('CONVERSION ') 269 output.print_name(node.conversion_name) 270 output.write(" FOR '%s' TO '%s'" % (node.for_encoding_name.value, 271 node.to_encoding_name.value)) 272 output.write(' FROM ') 273 output.print_name(node.func_name) 274 275 276@node_printer('CreateDomainStmt') 277def create_domain_stmt(node, output): 278 output.write('CREATE DOMAIN ') 279 output.print_name(node.domainname) 280 output.write(' AS ') 281 output.print_node(node.typeName) 282 if node.collClause: 283 output.print_node(node.collClause) 284 if node.constraints: 285 output.print_list(node.constraints, '', standalone_items=False) 286 287 288@node_printer('CreateEventTrigStmt') 289def create_event_trig_stmt(node, output): 290 output.write('CREATE EVENT TRIGGER ') 291 output.print_name(node.trigname) 292 output.write(' ON ') 293 output.print_name(node.eventname) 294 output.newline() 295 with output.push_indent(2): 296 if node.whenclause: 297 output.write('WHEN ') 298 output.print_list(node.whenclause, 'AND', relative_indent=-4) 299 output.newline() 300 output.write('EXECUTE PROCEDURE ') 301 output.print_name(node.funcname) 302 output.write('()') 303 304 305@node_printer('CreateEventTrigStmt', 'DefElem') 306def create_event_trig_stmt_def_elem(node, output): 307 output.print_name(node.defname) 308 output.write(' IN (') 309 output.print_list(node.arg, standalone_items=False) 310 output.write(')') 311 312 313@node_printer('CreateExtensionStmt') 314def create_extension_stmt(node, output): 315 output.write('CREATE EXTENSION ') 316 if node.if_not_exists: 317 output.write('IF NOT EXISTS ') 318 output.print_name(node.extname) 319 if node.options: 320 output.newline() 321 output.space(2) 322 output.write('WITH ') 323 output.print_list(node.options, '') 324 325 326@node_printer('CreateExtensionStmt', 'DefElem') 327def create_extension_stmt_def_elem(node, output): 328 option = node.defname.value 329 if option == 'cascade': 330 if node.arg.ival == 1: 331 output.write('CASCADE') 332 elif option == 'old_version': 333 output.write('from ') 334 output.print_node(node.arg) 335 elif option == 'new_version': 336 output.write('version ') 337 output.print_node(node.arg) 338 else: 339 output.write(option) 340 output.write(' ') 341 if option == 'schema': 342 output.print_name(node.arg) 343 else: 344 output.print_node(node.arg) 345 346 347@node_printer('CreateFdwStmt') 348def create_fdw_stmt(node, output): 349 output.write('CREATE FOREIGN DATA WRAPPER ') 350 output.print_name(node.fdwname) 351 if node.func_options: 352 output.newline() 353 output.space(2) 354 with output.push_indent(): 355 output.print_list(node.func_options, '') 356 if node.options: 357 output.newline() 358 with output.push_indent(2): 359 output.write('OPTIONS (') 360 output.print_list(node.options) 361 output.write(')') 362 363 364@node_printer('CreateFdwStmt', 'DefElem') 365def create_fdw_stmt_def_elem(node, output): 366 if node.parent_attribute[0] == 'options': 367 output.write(node.defname.value) 368 output.write(' ') 369 output.print_node(node.arg) 370 else: 371 output.write(node.defname.value.upper()) 372 output.write(' ') 373 output.print_name(node.arg) 374 375 376@node_printer('CreateForeignTableStmt') 377def create_foreign_table_stmt(node, output): 378 output.print_node(node.base) 379 if not node.base.tableElts: 380 output.newline() 381 output.write(' ') 382 output.write(' SERVER ') 383 output.print_name(node.servername) 384 if node.options: 385 output.newline() 386 with output.push_indent(2): 387 output.write('OPTIONS (') 388 output.print_list(node.options) 389 output.write(')') 390 391 392@node_printer('CreateForeignTableStmt', 'DefElem') 393def create_foreign_table_stmt_def_elem(node, output): 394 output.write(node.defname.value) 395 output.write(' ') 396 output.print_node(node.arg) 397 398 399@node_printer('CreateSchemaStmt') 400def create_schema_stmt(node, output): 401 output.write('CREATE SCHEMA ') 402 if node.if_not_exists: 403 output.write('IF NOT EXISTS ') 404 if node.schemaname: 405 output.print_name(node.schemaname) 406 if node.authrole: 407 output.swrite('AUTHORIZATION ') 408 output.print_node(node.authrole) 409 if node.schemaElts: 410 output.newline() 411 output.space(2) 412 with output.push_indent(): 413 output.print_list(node.schemaElts, '', standalone_items=True) 414 415 416@node_printer('CreateSeqStmt') 417def create_seq_stmt(node, output): 418 output.write('CREATE ') 419 if node.sequence.relpersistence == enums.RELPERSISTENCE_TEMP: 420 output.writes('TEMPORARY') 421 output.writes('SEQUENCE') 422 if node.if_not_exists: 423 output.writes('IF NOT EXISTS') 424 if node.sequence.schemaname is not Missing: 425 output.print_name(node.sequence.schemaname) 426 output.write('.') 427 output.print_name(node.sequence.relname) 428 if node.options: 429 output.newline() 430 output.space(2) 431 with output.push_indent(): 432 output.print_list(node.options, '') 433 434 435@node_printer('CreateSeqStmt', 'DefElem') 436def create_seq_stmt_def_elem(node, output): 437 option = node.defname.value 438 if option == 'cycle': 439 if node.arg.ival.value == 0: 440 output.write('NO ') 441 output.write('CYCLE') 442 elif option == 'increment': 443 output.write('INCREMENT BY ') 444 output.print_node(node.arg) 445 elif option == 'owned_by': 446 output.write('OWNED BY ') 447 output.print_name(node.arg) 448 elif option == 'start': 449 output.write('START WITH ') 450 output.print_node(node.arg) 451 else: 452 if node.arg is Missing: 453 output.write('NO ') 454 output.write(option.upper()) 455 if node.arg is not Missing: 456 output.write(' ') 457 output.print_node(node.arg) 458 if node.defaction != enums.DefElemAction.DEFELEM_UNSPEC: # pragma: nocover 459 raise NotImplementedError 460 461 462@node_printer('CreateStmt') 463def create_stmt(node, output): 464 output.writes('CREATE') 465 if node.parent_node.node_tag == 'CreateForeignTableStmt': 466 output.writes('FOREIGN') 467 else: 468 if node.relation.relpersistence == enums.RELPERSISTENCE_TEMP: 469 output.writes('TEMPORARY') 470 elif node.relation.relpersistence == enums.RELPERSISTENCE_UNLOGGED: 471 output.writes('UNLOGGED') 472 output.writes('TABLE') 473 if node.if_not_exists: 474 output.writes('IF NOT EXISTS') 475 output.print_node(node.relation) 476 if node.ofTypename: 477 output.write(' OF ') 478 output.print_name(node.ofTypename) 479 if node.partbound: 480 output.write(' PARTITION OF ') 481 output.print_list(node.inhRelations) 482 if node.tableElts: 483 output.write(' (') 484 output.newline() 485 output.space(2 if output.comma_at_eoln or len(node.tableElts) == 1 else 4) 486 output.print_list(node.tableElts) 487 output.newline() 488 output.write(')') 489 elif node.partbound: 490 output.newline() 491 output.write(' ') 492 with output.push_indent(): 493 first = True 494 if node.inhRelations and not node.partbound: 495 output.write(' INHERITS (') 496 output.print_list(node.inhRelations) 497 output.write(')') 498 first = False 499 if node.partbound: 500 if first: 501 first = False 502 else: # pragma: nocover 503 output.newline() 504 output.write(' FOR VALUES ') 505 output.print_node(node.partbound) 506 if node.partspec: 507 if first: 508 first = False 509 else: # pragma: nocover 510 output.newline() 511 output.write(' PARTITION BY ') 512 output.print_node(node.partspec) 513 if node.options: 514 if first: 515 first = False 516 else: 517 output.newline() 518 if len(node.options) == 1 and node.options[0].defname == 'oids': 519 output.write(' WITH') 520 if node.options[0].arg.ival.value == 0: 521 output.write 522 output.write('OUT') 523 output.write(' OIDS') 524 else: 525 output.write(' WITH (') 526 output.print_list(node.options) 527 output.write(')') 528 if node.oncommit != enums.OnCommitAction.ONCOMMIT_NOOP: 529 if first: 530 first = False 531 else: 532 output.newline() 533 output.write(' ON COMMIT ') 534 if node.oncommit == enums.OnCommitAction.ONCOMMIT_PRESERVE_ROWS: 535 output.write('PRESERVE ROWS') 536 elif node.oncommit == enums.OnCommitAction.ONCOMMIT_DELETE_ROWS: 537 output.write('DELETE ROWS') 538 elif node.oncommit == enums.OnCommitAction.ONCOMMIT_DROP: 539 output.write('DROP') 540 if node.tablespacename: 541 if first: 542 first = False 543 else: 544 output.newline() 545 output.write(' TABLESPACE ') 546 output.print_name(node.tablespacename) 547 548 549@node_printer('CreateTableAsStmt') 550def create_table_as_stmt(node, output): 551 output.writes('CREATE') 552 into = node.into 553 rel = into.rel 554 if rel.relpersistence == enums.RELPERSISTENCE_TEMP: 555 output.writes('TEMPORARY') 556 elif rel.relpersistence == enums.RELPERSISTENCE_UNLOGGED: 557 output.writes('UNLOGGED') 558 output.writes('TABLE') 559 if node.if_not_exists: 560 output.writes('IF NOT EXISTS') 561 output.print_node(rel) 562 if into.colNames: 563 output.write(' (') 564 output.print_name(into.colNames, ',') 565 output.write(')') 566 output.newline() 567 if into.options: 568 if len(into.options) == 1 and into.options[0].defname == 'oids': 569 output.space(2) 570 output.write('WITH') 571 if into.options[0].arg.ival.value == 0: 572 output.write 573 output.write('OUT') 574 output.write(' OIDS') 575 else: 576 output.space(2) 577 output.write('WITH (') 578 output.print_list(into.options) 579 output.write(')') 580 output.newline() 581 if into.onCommit != enums.OnCommitAction.ONCOMMIT_NOOP: 582 output.space(2) 583 output.write('ON COMMIT ') 584 if into.onCommit == enums.OnCommitAction.ONCOMMIT_PRESERVE_ROWS: 585 output.write('PRESERVE ROWS') 586 elif into.onCommit == enums.OnCommitAction.ONCOMMIT_DELETE_ROWS: 587 output.write('DELETE ROWS') 588 elif into.onCommit == enums.OnCommitAction.ONCOMMIT_DROP: 589 output.write('DROP') 590 output.newline() 591 if into.tableSpaceName: 592 output.space(2) 593 output.write('TABLESPACE ') 594 output.print_name(into.tableSpaceName) 595 output.newline() 596 output.space(2) 597 output.write('AS ') 598 if ((node.query.targetList is not Missing 599 and node.query.whereClause is Missing 600 and len(node.query.targetList[0].val.fields) == 1 601 and node.query.targetList[0].val.fields[0].node_tag == 'A_Star')): 602 output.write('TABLE ') 603 output.print_list(node.query.fromClause) 604 else: 605 with output.push_indent(): 606 output.print_node(node.query) 607 if node.into.skipData: 608 output.newline() 609 output.space(2) 610 output.write('WITH NO DATA') 611 612 613@node_printer('CreatedbStmt') 614def createdb_stmt(node, output): 615 output.write('CREATE DATABASE ') 616 output.print_name(node.dbname) 617 if node.options: 618 output.newline() 619 output.space(2) 620 output.write('WITH ') 621 output.print_list(node.options, '') 622 623 624@node_printer('CreatedbStmt', 'DefElem') 625def create_db_stmt_def_elem(node, output): 626 option = node.defname.value 627 if option == 'connection_limit': 628 output.write('connection limit') 629 else: 630 output.print_node(node.defname) 631 if node.arg is not Missing: 632 output.write(' = ') 633 if isinstance(node.arg, List) or option in ('allow_connections', 'is_template'): 634 output.write(node.arg.string_value) 635 else: 636 output.print_node(node.arg) 637 638 639@node_printer('DefineStmt') 640def define_stmt(node, output): 641 output.write('CREATE ') 642 output.writes(OBJECT_NAMES[node.kind.value]) 643 if node.if_not_exists: 644 output.write('IF NOT EXISTS ') 645 output.print_list(node.defnames, '.', standalone_items=False, are_names=True, 646 is_symbol=node.kind == enums.ObjectType.OBJECT_OPERATOR) 647 output.write(' ') 648 if node.args is not Missing: 649 output.write('(') 650 # args is actually a tuple (list-of-nodes, integer): the integer value, if different 651 # from -1, is the number of nodes representing the actual arguments, remaining are 652 # ORDER BY 653 args, count = node.args 654 count = count.ival.value 655 if count == -1: 656 output.print_list(args, standalone_items=False) 657 else: 658 output.print_list(args[:count], standalone_items=False) 659 output.write(' ORDER BY ') 660 output.print_list(args[count:], standalone_items=False) 661 output.write(') ') 662 if ((node.kind == enums.ObjectType.OBJECT_COLLATION 663 and len(node.definition) == 1 664 and node.definition[0].defname == 'from')): 665 output.write('FROM ') 666 output.print_name(node.definition[0].arg) 667 else: 668 output.write('(') 669 output.newline() 670 output.space(2 if output.comma_at_eoln or len(node.definition) == 1 else 4) 671 output.print_list(node.definition) 672 output.newline() 673 output.write(')') 674 675 676@node_printer('DefElem') 677def def_elem(node, output): 678 output.print_node(node.defname) 679 if node.arg is not Missing: 680 output.write(' = ') 681 if isinstance(node.arg, List): 682 output.write(node.arg.string_value) 683 else: 684 output.print_node(node.arg) 685 if node.defaction != enums.DefElemAction.DEFELEM_UNSPEC: # pragma: nocover 686 raise NotImplementedError 687 688 689@node_printer('DefineStmt', 'DefElem') 690def define_stmt_def_elem(node, output): 691 output.print_node(node.defname) 692 if node.arg is not Missing: 693 output.write(' = ') 694 if isinstance(node.arg, List): 695 is_symbol = node.defname in ('commutator', 'negator') 696 if is_symbol and len(node.arg) > 1: 697 output.write('OPERATOR(') 698 output.print_symbol(node.arg) 699 output.write(')') 700 else: 701 output.print_symbol(node.arg) 702 else: 703 output.print_node(node.arg) 704 if node.defaction != enums.DefElemAction.DEFELEM_UNSPEC: # pragma: nocover 705 raise NotImplementedError 706 707 708@node_printer('DropdbStmt') 709def drop_db_stmt(node, output): 710 output.write('DROP DATABASE') 711 if node.missing_ok: 712 output.write(' IF EXISTS') 713 output.write(' ') 714 output.print_name(node.dbname) 715 716 717@node_printer('DropOwnedStmt') 718def drop_owned_stmt(node, output): 719 output.write('DROP OWNED BY ') 720 output.print_list(node.roles, are_names=True) 721 if node.behavior == enums.DropBehavior.DROP_CASCADE: 722 output.write(' CASCADE') 723 elif node.behavior == enums.DropBehavior.DROP_RESTRICT: 724 output.write(' RESTRICT') 725 726 727@node_printer('DropRoleStmt') 728def drop_role_stmt(node, output): 729 output.write('DROP ROLE') 730 if node.missing_ok: 731 output.write(' IF EXISTS') 732 output.write(' ') 733 output.print_list(node.roles, are_names=True) 734 735 736@node_printer('DropStmt') 737def drop_stmt(node, output): 738 otypes = enums.ObjectType 739 output.write('DROP ') 740 output.writes(OBJECT_NAMES[node.removeType.value]) 741 if node.removeType == otypes.OBJECT_INDEX: 742 if node.concurrent: 743 output.write(' CONCURRENTLY') 744 if node.missing_ok: 745 output.write(' IF EXISTS') 746 output.write(' ') 747 if node.objects: 748 if node.removeType in (otypes.OBJECT_OPCLASS, otypes.OBJECT_OPFAMILY): 749 nodes = list(node.objects[0]) 750 using = nodes.pop(0) 751 output.print_name(nodes) 752 output.write(' USING ') 753 output.print_name(using) 754 elif node.removeType == otypes.OBJECT_TRANSFORM: 755 nodes = list(node.objects[0]) 756 output.write('FOR ') 757 output.print_name(nodes.pop(0)) 758 output.write(' LANGUAGE ') 759 output.print_name(nodes) 760 elif node.removeType in (otypes.OBJECT_POLICY, 761 otypes.OBJECT_RULE, 762 otypes.OBJECT_TRIGGER): 763 nodes = list(node.objects[0]) 764 on = nodes.pop(0) 765 output.print_name(nodes) 766 output.write(' ON ') 767 output.print_name(on) 768 elif isinstance(node.objects[0], List): 769 if node.objects[0][0].node_tag != 'String': 770 output.print_lists(node.objects, ' AS ', standalone_items=False, 771 are_names=True) 772 else: 773 output.print_lists(node.objects, sep='.', sublist_open='', sublist_close='', 774 standalone_items=False, are_names=True) 775 else: 776 output.print_list(node.objects, ',', standalone_items=False, are_names=True) 777 if node.behavior == enums.DropBehavior.DROP_CASCADE: 778 output.write(' CASCADE') 779 elif node.behavior == enums.DropBehavior.DROP_RESTRICT: 780 output.write(' RESTRICT') 781 782 783@node_printer('DropSubscriptionStmt') 784def drop_subscription_stmt(node, output): 785 output.write('DROP SUBSCRIPTION') 786 if node.missing_ok: 787 output.write(' IF EXISTS') 788 output.write(' ') 789 output.print_name(node.subname) 790 if node.behavior == enums.DropBehavior.DROP_CASCADE: 791 output.write(' CASCADE') 792 elif node.behavior == enums.DropBehavior.DROP_RESTRICT: 793 output.write(' RESTRICT') 794 795 796@node_printer('DropTableSpaceStmt') 797def drop_table_space_stmt(node, output): 798 output.write('DROP TABLESPACE') 799 if node.missing_ok: 800 output.write(' IF EXISTS') 801 output.write(' ') 802 output.print_name(node.tablespacename) 803 804 805@node_printer('DropUserMappingStmt') 806def drop_user_mapping_stmt(node, output): 807 output.write('DROP USER MAPPING') 808 if node.missing_ok: 809 output.write(' IF EXISTS') 810 output.write(' FOR ') 811 output.print_node(node.user) 812 output.write(' SERVER ') 813 output.print_name(node.servername) 814 815 816@node_printer('FunctionParameter') 817def function_parameter(node, output): 818 if node.mode is not Missing: 819 pm = enums.FunctionParameterMode 820 if node.mode == pm.FUNC_PARAM_IN: 821 pass # omit the default, output.write('IN ') 822 elif node.mode == pm.FUNC_PARAM_OUT: 823 output.write('OUT ') 824 elif node.mode == pm.FUNC_PARAM_INOUT: 825 output.write('INOUT ') 826 elif node.mode == pm.FUNC_PARAM_VARIADIC: 827 output.write('VARIADIC ') 828 else: 829 raise NotImplementedError 830 if node.name: 831 output.print_name(node.name) 832 output.write(' ') 833 output.print_node(node.argType) 834 if node.defexpr is not Missing: 835 output.write(' = ') 836 output.print_node(node.defexpr) 837 838 839@node_printer('IndexStmt') 840def index_stmt(node, output): 841 output.write('CREATE ') 842 if node.unique: 843 output.write('UNIQUE ') 844 output.write('INDEX ') 845 if node.concurrent: 846 output.write('CONCURRENTLY ') 847 if node.if_not_exists: 848 output.write('IF NOT EXISTS ') 849 if node.idxname: 850 output.print_name(node.idxname) 851 output.newline() 852 with output.push_indent(2): 853 output.write('ON ') 854 output.print_node(node.relation) 855 if node.accessMethod != 'btree': 856 output.write('USING ') 857 output.print_name(node.accessMethod) 858 output.write(' (') 859 output.print_list(node.indexParams) 860 output.write(')') 861 if node.options: 862 output.newline() 863 output.write('WITH (') 864 output.print_list(node.options) 865 output.write(')') 866 if node.tableSpace: 867 output.newline() 868 output.write('TABLESPACE ') 869 output.print_name(node.tableSpace) 870 if node.whereClause: 871 output.newline() 872 output.write('WHERE ') 873 output.print_node(node.whereClause) 874 875 876@node_printer('ObjectWithArgs') 877def object_with_args(node, output): 878 # Special treatment for OPERATOR object inside DROP or COMMENT 879 if (((node.parent_node.removeType or node.parent_node.objtype) 880 == enums.ObjectType.OBJECT_OPERATOR)): 881 output.write(node.objname.string_value) 882 if not node.args_unspecified: 883 output.write(' ') 884 else: 885 output.print_name(node.objname) 886 if not node.args_unspecified: 887 output.write('(') 888 output.print_list(node.objargs, ',', standalone_items=False) 889 output.write(')') 890 891 892@node_printer('PartitionBoundSpec') 893def partition_bound_spec(node, output): 894 if node.strategy.value == enums.PARTITION_STRATEGY_RANGE: 895 output.swrite('FROM (') 896 output.print_list(node.lowerdatums) 897 output.write(') TO (') 898 output.print_list(node.upperdatums) 899 output.write(')') 900 else: 901 output.swrite('IN (') 902 output.print_list(node.listdatums) 903 output.write(')') 904 905 906@node_printer('PartitionElem') 907def partition_elem(node, output): 908 if node.name: 909 output.print_name(node.name) 910 elif node.expr: 911 output.print_node(node.expr) 912 if node.collation or node.opclass: # pragma: nocover 913 raise NotImplementedError 914 915 916@node_printer('PartitionRangeDatum') 917def partition_range_datum(node, output): 918 if node.kind == enums.PartitionRangeDatumKind.PARTITION_RANGE_DATUM_MINVALUE: 919 output.write('MINVALUE') 920 elif node.kind == enums.PartitionRangeDatumKind.PARTITION_RANGE_DATUM_MAXVALUE: 921 output.write('MAXVALUE') 922 else: 923 output.print_node(node.value) 924 925 926@node_printer('PartitionSpec') 927def partition_spec(node, output): 928 output.print_node(node.strategy) 929 output.write(' (') 930 output.print_list(node.partParams) 931 output.write(')') 932 933 934@node_printer('RoleSpec') 935def role_spec(node, output): 936 if node.roletype == enums.RoleSpecType.ROLESPEC_CURRENT_USER: 937 output.write('CURRENT_USER') 938 elif node.roletype == enums.RoleSpecType.ROLESPEC_SESSION_USER: 939 output.write('SESSION_USER') 940 elif node.roletype == enums.RoleSpecType.ROLESPEC_PUBLIC: 941 output.write('PUBLIC') 942 else: 943 output.print_name(node.rolename) 944