From: | Peter Smith <smithpb2250(at)gmail(dot)com> |
---|---|
To: | vignesh C <vignesh21(at)gmail(dot)com> |
Cc: | Zheng Li <zhengli10(at)gmail(dot)com>, Ajin Cherian <itsajin(at)gmail(dot)com>, "houzj(dot)fnst(at)fujitsu(dot)com" <houzj(dot)fnst(at)fujitsu(dot)com>, Amit Kapila <amit(dot)kapila16(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Japin Li <japinli(at)hotmail(dot)com>, Alvaro Herrera <alvherre(at)alvh(dot)no-ip(dot)org>, Dilip Kumar <dilipbalaut(at)gmail(dot)com>, rajesh singarapu <rajesh(dot)rs0541(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: Support logical replication of DDLs |
Date: | 2022-10-06 08:30:47 |
Message-ID: | CAHut+Pt=n55fROZJHEp9Aa1CKvDSHTgxGk+jt4-5NjkbAYaRgA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general pgsql-hackers |
The patches here are quite large, so for this review post, I have only
done a quick check for cosmetic stuff in the comments of patch
v24-0001.
~
I did this mostly just by cutting/pasting the whole patch text into a
grammar/spell-checker to see what it reported. Please use the same
strategy prior to posting future patch versions, because it will be
way more efficient/easier for the author to spend a few minutes to fix
everything like this up-front before posting, rather than getting a
flood of review comments to deal with (like this post) about such
stuff.
(BTW, most of these suggestions are just verbatim what my
grammar/spell-checker told me)
======
1. Commit comment
(Note #2) Note that, for ATTACH/DETACH PARTITION, we haven't added
extra logic on
subscriber to handle the case where the table on publisher is a PARTITIONED
TABLE while the target table on subcriber side is NORMAL table. We will
research this more and improve this later.
SUGGESTION (minor changes + fix typo)
(Note #2) Note that for ATTACH/DETACH PARTITION we haven't added extra logic on
the subscriber to handle the case where the table on the publisher is
a PARTITIONED
TABLE while the target table on the subscriber is a NORMAL table. We will
research this more and improve it later.
======
2. GENERAL - uppercase the comments
Please make all your single-line comments start with uppercase for consistency.
Here are some examples to fix:
Line 303: + /* add the "ON table" clause */
Line 331: + /* add the USING clause, if any */
Line 349: + /* add the WITH CHECK clause, if any */
Line 653: + /* otherwise, WITH TZ is added by typmod. */
Line 663: + /* otherwise, WITH TZ is added by typmode. */
Line 1946: + /* build list of privileges to grant/revoke */
Line 2017: + /* target objects. We use object identities here */
Line 2041: + /* list of grantees */
Line 2053: + /* the wording of the grant option is variable ... */
Line 2632: + /* skip this one; we add one unconditionally below */
Line 2660: + /* done */
Line 2768: + /* add HANDLER clause */
Line 2780: + /* add VALIDATOR clause */
Line 2792: + /* add an OPTIONS clause, if any */
Line 2845: + /* add HANDLER clause */
Line 2859: + /* add VALIDATOR clause */
Line 2877: + /* add an OPTIONS clause, if any */
Line 5024: + /* add the rest of the stuff */
Line 5040: + /* add the rest of the stuff */
Line 5185: + /* a new constraint has a name and definition */
Line 5211: + /* done */
Line 6124: + /* add a CONCURRENTLY clause */
Line 6127: + /* add the matview name */
Line 6131: + /* add a WITH NO DATA clause */
Line 6302: + /* reloptions */
Line 6310: + /* tablespace */
Line 6592: + /* deconstruct the name list */
Line 6636: + /* deconstruct the name list */
Line 6725: + /* obtain object tuple */
Line 6729: + /* obtain namespace */
------
3. Grammar/Spelling
3a. - format_type_detailed
+ * - nspid is the schema OID. For certain SQL-standard types which have weird
+ * typmod rules, we return InvalidOid; caller is expected to not schema-
+ * qualify the name nor add quotes to the type name in this case.
"caller" -> "the caller"
~
3b. - format_type_detailed
+ * - typemodstr is set to the typemod, if any, as a string with parens
"parens" -> "parentheses"
~
3c. - format_type_detailed
+ else
+ /* otherwise, WITH TZ is added by typmode. */
+ *typname = pstrdup("TIME");
"typmode" -> "typmod" ?
~
3d. - new_objtree_for_qualname
+ * A helper routine to setup %{}D and %{}O elements.
"setup" -> "set up"
~
3e. - new_objtree_for_type
+/*
+ * A helper routine to setup %{}T elements.
+ */
+static ObjTree *
+new_objtree_for_type(Oid typeId, int32 typmod)
"setup" -> "set up"
~
3f. - pg_get_indexdef_detailed
+/*
+ * Return an index definition, split in several pieces.
+ *
+ * A large amount of code is duplicated from pg_get_indexdef_worker, but
+ * control flow is different enough that it doesn't seem worth keeping them
+ * together.
+ */
+static void
+pg_get_indexdef_detailed(Oid indexrelid,
"split in" -> "split into"
~
3g. - ddl_deparse_to_json
+ * The command is expanded fully, so that there are no ambiguities even in the
+ * face of search_path changes.
+ */
+Datum
+ddl_deparse_to_json(PG_FUNCTION_ARGS)
"fully, so" -> "fully so"
~
3h. -deparse_AlterFunction
+ * Given a function OID and the parsetree that created it, return the JSON
+ * blob representing the alter command.
+ */
"the parsetree" -> "the parse tree"
~
3i. - deparse_AlterObjectSchemaStmt
+/*
+ * deparse an ALTER ... SET SCHEMA command.
+ */
+static ObjTree *
+deparse_AlterObjectSchemaStmt(ObjectAddress address, Node *parsetree,
"deparse" -> "Deparse"
~
3j. deparse_AlterObjectSchemaStmt
+ /*
+ * Since the command has already taken place from the point of view of
+ * catalogs, getObjectIdentity returns the object name with the already
+ * changed schema. The output of our deparsing must return the original
+ * schema name however, so we chop the schema name off the identity string
+ * and then prepend the quoted schema name.
"name however," -> "name, however,"
~
3k. - deparse_GrantStmt
+ /* build list of privileges to grant/revoke */
+ if (istmt->all_privs)
"build list" -> "build a list"
~
3l. - deparse_AlterTypeSetStmt
+ * Deparse an AlterTypeStmt.
+ *
+ * Given a type OID and a parsetree that modified it, return an ObjTree
+ * representing the alter type.
+ */
+static ObjTree *
+deparse_AlterTypeSetStmt(Oid objectId, Node *cmd)
"parsetree" -> "parse tree"
~
3m. - deparse_CompositeTypeStmt
+ * Deparse a CompositeTypeStmt (CREATE TYPE AS)
+ *
+ * Given a type OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3n. - deparse_CreateEnumStmt
+/*
+ * Deparse a CreateEnumStmt (CREATE TYPE AS ENUM)
+ *
+ * Given a type OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3o. - deparse_CreateExtensionStmt
+/*
+ * deparse_CreateExtensionStmt
+ * deparse a CreateExtensionStmt
+ *
+ * Given an extension OID and the parsetree that created it, return the JSON
+ * blob representing the creation command.
+ *
+ */
"parsetree" -> "parse tree"
~
3p. - deparse_CreateFdwStmt
+/*
+ * deparse_CreateFdwStmt
+ * Deparse a CreateFdwStmt (CREATE FOREIGN DATA WRAPPER)
+ *
+ * Given a trigger OID and the parsetree that created it,
+ * return an ObjTree representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3q. - deparse_AlterFdwStmt
+/*
+ * deparse_AlterFdwStmt
+ * Deparse an AlterFdwStmt (ALTER FOREIGN DATA WRAPPER)
+ *
+ * Given a function OID and the parsetree that create it, return the
+ * JSON blob representing the alter command.
+ */
"parsetree" -> "parse tree"
"create it" -> "created it"
3r.
+ /*
+ * Iterate through options, to see what changed, but use catalog as basis
+ * for new values.
+ */
"as basis" -> "as a basis"
~
3s.
+/*
+ * Deparse a CREATE TYPE AS RANGE statement
+ *
+ * Given a type OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3t. - deparse_AlterEnumStmt
+/*
+ * Deparse an AlterEnumStmt.
+ *
+ * Given a type OID and a parsetree that modified it, return an ObjTree
+ * representing the alter type.
+ */
"parsetree" -> "parse tree"
~
3u. - deparse_AlterTableStmt
+ /*
+ * We don't support replicating ALTER TABLE which contains volatile
+ * functions because It's possible the functions contain DDL/DML in
+ * which case these opertions will be executed twice and cause
+ * duplicate data. In addition, we don't know whether the tables being
+ * accessed by these DDL/DML are published or not. So blindly allowing
+ * such functions can allow unintended clauses like the tables accessed
+ * in those functions may not even exist on the subscriber-side.
+ */
"opertions" -> "operations"
"subscriber-side." -> "subscriber."
~
3v. - deparse_ColumnDef
+ * Deparse a ColumnDef node within a regular (non typed) table creation.
"non typed" -> "non-typed"
~
3w. - deparse_ColumnDef
+ /*
+ * Emit a NOT NULL declaration if necessary. Note that we cannot trust
+ * pg_attribute.attnotnull here, because that bit is also set when
+ * primary keys are specified; and we must not emit a NOT NULL
+ * constraint in that case, unless explicitely specified. Therefore,
+ * we scan the list of constraints attached to this column to determine
+ * whether we need to emit anything.
+ * (Fortunately, NOT NULL constraints cannot be table constraints.)
+ *
+ * In the ALTER TABLE cases, we also add a NOT NULL if the colDef is
+ * marked is_not_null.
+ */
"specified; and we" -> "specified; we"
"explicitely" -> "explicitly"
~
3x. - deparse_CreateDomain
+/*
+ * Deparse the CREATE DOMAIN
+ *
+ * Given a function OID and the parsetree that created it, return the JSON
+ * blob representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3y. - deparse_CreateFunction
+/*
+ * Deparse a CreateFunctionStmt (CREATE FUNCTION)
+ *
+ * Given a function OID and the parsetree that created it, return the JSON
+ * blob representing the creation command.
+ */
"parsetree" -> "parse tree"
~
3z. - deparse_CreateFunction
+ /*
+ * Now iterate over each parameter in the parsetree to create the
+ * parameters array.
+ */
"parsetree" -> "parse tree"
~
4a. - deparse_CreateFunction
+ /*
+ * A PARAM_TABLE parameter indicates end of input arguments; the
+ * following parameters are part of the return type. We ignore them
+ * here, but keep track of the current position in the list so that
+ * we can easily produce the return type below.
+ */
"end" -> "the end"
~
4b. - deparse_CreateOpClassStmt
+ /* Don't deparse sql commands generated while creating extension */
+ if (cmd->in_extension)
+ return NULL;
"sql" -> "SQL"
~
4c. - deparse_CreateOpClassStmt
/*
+ * Add the FAMILY clause; but if it has the same name and namespace as the
+ * opclass, then have it expand to empty, because it would cause a failure
+ * if the opfamily was created internally.
+ */
"clause; " -> "clause, "
"empty," -> "empty"
~
4d. - deparse_CreateOpFamily
+/*
+ * Deparse a CreateTrigStmt (CREATE OPERATOR FAMILY)
+ *
+ * Given a trigger OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
4e. - deparse_CreateSchemaStmt
+/*
+ * Deparse a CreateSchemaStmt.
+ *
+ * Given a schema OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ *
+ */
"parsetree" -> "parse tree"
~
4f. - deparse_CreateSeqStmt
+/*
+ * Deparse a CreateSeqStmt.
+ *
+ * Given a sequence OID and the parsetree that create it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
"create it" -> "created it"
~
4g. - deparse_CreateStmt
+/*
+ * Deparse a CreateStmt (CREATE TABLE).
+ *
+ * Given a table OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
4h.
+ /*
+ * Typed tables and partitions use a slightly different format string: we
+ * must not put table_elements with parents directly in the fmt string,
+ * because if there are no options the parens must not be emitted; and
+ * also, typed tables do not allow for inheritance.
+ */
"parens" -> "parentheses"
~
4i. - deparse_CreateStmt
+ /*
+ * We can't put table elements directly in the fmt string as an array
+ * surrounded by parens here, because an empty clause would cause a
+ * syntax error. Therefore, we use an indirection element and set
+ * present=false when there are no elements.
+ */
"parens" -> "parentheses"
~
4j. - deparse_CreateStmt
+ /*
+ * Get pg_class.relpartbound. We cannot use partbound in the
+ * parsetree directly as it's the original partbound expression
+ * which haven't been transformed.
+ */
"parsetree" -> "parse tree" ? maybe this one if ok if it referring to
the parameter with this name.
~
4k. - deparse_DefineStmt_Operator
+/*
+ * Deparse a DefineStmt (CREATE OPERATOR)
+ *
+ * Given a trigger OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parse tree"
~
4l. - deparse_CreateTrigStmt
+/*
+ * Deparse a CreateTrigStmt (CREATE TRIGGER)
+ *
+ * Given a trigger OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ */
"parsetree" -> "parsetree"
~
4m. - deparse_RefreshMatViewStmt
+/*
+ * Deparse a RefreshMatViewStmt (REFRESH MATERIALIZED VIEW)
+ *
+ * Given a materialized view OID and the parsetree that created it, return an
+ * ObjTree representing the refresh command.
+ */
"parseree" -> "parse tree"
~
4n. - deparse_IndexStmt
+/*
+ * Deparse an IndexStmt.
+ *
+ * Given an index OID and the parsetree that created it, return an ObjTree
+ * representing the creation command.
+ *
+ * If the index corresponds to a constraint, NULL is returned.
+ */
"parsetree" -> "parse tree"
~
4o. - deparse_InhRelations
+/*
+ * Deparse the INHERITS relations.
+ *
+ * Given a table OID, return a schema qualified table list representing
+ * the parent tables.
+ */
+static List *
+deparse_InhRelations(Oid objectId)
"schema qualified" -> "schema-qualified"
~
4p. - deparse_OnCommitClause
+/*
+ * Deparse the ON COMMMIT ... clause for CREATE ... TEMPORARY ...
+ */
+static ObjTree *
+deparse_OnCommitClause(OnCommitAction option)
"COMMMIT" -> "COMMIT"
~
4q. - deparse_RuleStmt
+/*
+ * Deparse a RuleStmt (CREATE RULE).
+ *
+ * Given a rule OID and the parsetree that created it, return an ObjTree
+ * representing the rule command.
+ */
"parsetree" -> "parse tree"
~
4r. - deparse_utility_command
+ /*
+ * Allocate everything done by the deparsing routines into a temp context,
+ * to avoid having to sprinkle them with memory handling code; but allocate
+ * the output StringInfo before switching.
+ */
"code; " -> "code, "
~
4s. - deparse_utility_command
+ /*
+ * Many routines underlying this one will invoke ruleutils.c functionality
+ * in order to obtain deparsed versions of expressions. In such results,
+ * we want all object names to be qualified, so that results are "portable"
+ * to environments with different search_path settings. Rather than inject
+ * what would be repetitive calls to override search path all over the
+ * place, we do it centrally here.
+ */
"in order to" => "to"
~
4t. - convSpecifier
+/*
+ * Conversion specifier, it determines how we expand the json element into
+ * string.
+ */
SUGGESTION
Conversion specifier which determines how we expand the json element
into a string.
~
4u. - json_trivalue
+/*
+ * A ternary value which represents a boolean type JsonbValue.
+ */
"which represents" -> "that represents"
~
4v. - expand_fmt_recursive
+ /*
+ * Scan the mandatory element name. Allow for an array separator
+ * (which may be the empty string) to be specified after colon.
+ */
"after colon" -> "after a colon"
~
4w. - expand_jsonval_string
+/*
+ * Expand a json value as a string. The value must be of type string or of
+ * type object. In the latter case it must contain a "fmt" element which will
+ * be recursively expanded; also, if the object contains an element "present"
+ * and it is set to false, the expansion is the empty string.
+ *
+ * Returns false if no actual expansion was made due to the "present" flag
+ * being set to "false".
+ */
"latter case" -> "latter case,"
~
4x. - format_procedure_args_internal
+/*
+ * Append the parenthised arguments of the given pg_proc row into the output
+ * buffer. force_qualify indicates whether to schema-qualify type names
+ * regardless of visibility.
+ */
"parenthised" -> "parenthesized "
~
4y.
+/*
+ * Internal version that returns definition of a CONSTRAINT command
+ */
"definition" -> "the definition"
======
5. Function comment inconsistencies
5a.
Sometimes the function name is repeated in the comment and sometimes it is not.
e.g. compare deparse_CreateEnumStmt() versus deparse_CreateExtensionStmt(), etc.
(IMO there is no need to repeat the function name)
~
5b.
Sometimes the deparse function comments are verbose and say like:
+ * Given a type OID and a parsetree that modified it, return an ObjTree
+ * representing the alter type.
but sometimes - like deparse_AlterExtensionStmt() etc. - they don't
bother to say anything at all.
e.g.
+/*
+ * Deparse ALTER EXTENSION .. UPDATE TO VERSION
+ */
+static ObjTree *
+deparse_AlterExtensionStmt(Oid objectId, Node *parsetree)
Either it is useful, so say it always, or it is not useful, so say it
never. Pick one.
------
6. GENERAL - json
IMO change "json" -> "JSON" everywhere.
Here are some examples:
Line 7605: + * Conversion specifier, it determines how we expand the
json element into
Line 7699: + errmsg("missing element \"%s\" in json object", keyname)));
Line 7857: + * Expand a json value as a quoted identifier. The value
must be of type string.
Line 7872: + * Expand a json value as a dot-separated-name. The value
must be of type
Line 7908: + * Expand a json value as a type name.
Line 7966: + * Expand a json value as an operator name
Line 7993: + * Expand a json value as a string. The value must be of
type string or of
Line 8031: + * Expand a json value as a string literal.
Line 8070: + * Expand a json value as an integer quantity.
Line 8083: + * Expand a json value as a role name. If the is_public
element is set to
Line 8111: + * Expand one json element into the output StringInfo
according to the
Line 8807: +{ oid => '4642', descr => 'deparse the DDL command into
json format string',
Line 8810: +{ oid => '4643', descr => 'expand json format DDL to a
plain DDL command',
------
Kind Regards,
Peter Smith.
Fujitsu Australia
From | Date | Subject | |
---|---|---|---|
Next Message | Gavan Schneider | 2022-10-06 08:49:58 | Re: ('dog$house' = quote_ident('dog$house')) is surprisingly FALSE |
Previous Message | Bryn Llewellyn | 2022-10-06 05:58:04 | Re: ('dog$house' = quote_ident('dog$house')) is surprisingly FALSE |
From | Date | Subject | |
---|---|---|---|
Next Message | Drouvot, Bertrand | 2022-10-06 08:36:01 | Re: Query Jumbling for CALL and SET utility statements |
Previous Message | kato-sho@fujitsu.com | 2022-10-06 08:12:37 | fix comment typo in xlogprefetcher.c |