Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o6VFK-0006z5-Tx for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Jun 2022 10:48:35 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1o6VFH-0003sC-LF for pgsql-hackers@arkaria.postgresql.org; Wed, 29 Jun 2022 10:48:31 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1o6VFH-0003s3-5e for pgsql-hackers@lists.postgresql.org; Wed, 29 Jun 2022 10:48:31 +0000 Received: from mail-yb1-xb33.google.com ([2607:f8b0:4864:20::b33]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1o6VFA-0005tY-9O for pgsql-hackers@lists.postgresql.org; Wed, 29 Jun 2022 10:48:29 +0000 Received: by mail-yb1-xb33.google.com with SMTP id l11so27159441ybu.13 for ; Wed, 29 Jun 2022 03:48:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=g13PJcH73/tmcshW7LpD7/1/8Tvk6jUVrI9jI3H9DnI=; b=CTdrnWHxsHmvpzl7Nr7PIhMq4Nu3ntcgZp290xEKWU37Cl3fvnoiYDtFPcfskNu9OJ fLpLgNfOSHgrTOxATEVgjfSFMAdf6SVw+RBjH/1Vhq1oKi2HETEqsdxZsxHl1DofkI+l WgcdBchiPlSSIJqMC66dEka0cwx/ttwjpn7HgaCdPy20cvV2+yzwCw1Z9CYevd36KnzD ZVFPPZTVau7+OoaC1Gx3++TwSZ0Ol/gk6l8HLvpL2tfH33AfUvyKyrgyWWO+HmyJbAAa JMgalxw0mpJjceKXcmkjjfAVOooymTn1JLZlgUhORzODR2mbcqmaXpLoudACS3zSYaP4 KewQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=g13PJcH73/tmcshW7LpD7/1/8Tvk6jUVrI9jI3H9DnI=; b=NRkHCCCrbadVXSKGG2Z+XnSW0E4ox6KD2VvfaRfdrGACJocaTRScK5Ht8axlTSwybu BxcKyjKGmk6YAmQvHWq8ncSiws1ZT0pim61/cInim/6FV+VSNdMo6cO9wEHA4S8QO+6K asWC+Zy4bCgPEz1uIFIlQKq5sjKYPiFEUSVfc1d1T2sgixuGxgdnMC1MjK1Xr+iqWgdo c+mMCj7YhUPYrCLDLKaPfFsRVpyXh1lAael9cfvmEH8tSUw0hNDhlopRWSRk7A1Euh66 LT8T0Lqs5BNTfzRuYAV5jjkid26RL/Sre112apYWvRTa69Jgo+LIZsGvDeoNVT37s/+g K7+w== X-Gm-Message-State: AJIora/oVxcFLeliqoCOmqRxP+LPxGATDDUJjTCDQgGEOQRHMma9Ccgi phN3aPhcNbGtMifvuNURT8s2f3pIlphwF25RpOY= X-Google-Smtp-Source: AGRyM1troZ3F5fE5n37Wo1bohL++qRqQ7x87ORlgtLQrf6hjAcCVv367naBag8rXBMxC1GbQz9oIGOT75/0hNcJXveU= X-Received: by 2002:a25:cbd2:0:b0:66b:4f19:6b7e with SMTP id b201-20020a25cbd2000000b0066b4f196b7emr2599357ybg.349.1656499703177; Wed, 29 Jun 2022 03:48:23 -0700 (PDT) MIME-Version: 1.0 References: <202203162206.7spggyktx63e@alvherre.pgsql> In-Reply-To: From: Amit Kapila Date: Wed, 29 Jun 2022 16:18:12 +0530 Message-ID: Subject: Re: Support logical replication of DDLs To: "houzj.fnst@fujitsu.com" Cc: Masahiko Sawada , Japin Li , Alvaro Herrera , Dilip Kumar , rajesh singarapu , PostgreSQL Hackers , Zheng Li Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Jun 29, 2022 at 3:24 PM houzj.fnst@fujitsu.com wrote: > > On Wednesday, June 29, 2022 11:07 AM Amit Kapila wrote: > > > > On Tue, Jun 28, 2022 at 5:43 PM Amit Kapila > > wrote: > > > > > > 5. > > > +static ObjTree * > > > +deparse_CreateStmt(Oid objectId, Node *parsetree) > > > { > > > ... > > > + tmp = new_objtree_VA("TABLESPACE %{tablespace}I", 0); if > > > + (node->tablespacename) append_string_object(tmp, "tablespace", > > > + node->tablespacename); else { append_null_object(tmp, "tablespace"); > > > + append_bool_object(tmp, "present", false); } > > > + append_object_object(createStmt, "tablespace", tmp); > > > ... > > > } > > > > > > Why do we need to append the objects (tablespace, with clause, etc.) > > > when they are not present in the actual CREATE TABLE statement? The > > > reason to ask this is that this makes the string that we want to send > > > downstream much longer than the actual statement given by the user on > > > the publisher. > > > > > > > After thinking some more on this, it seems the user may want to optionally > > change some of these attributes, for example, on the subscriber, it may want to > > associate the table with a different tablespace. I think to address that we can > > append these additional attributes optionally, say via an additional parameter > > (append_all_options/append_all_attributes or something like that) in exposed > > APIs like deparse_utility_command(). > > I agree and will research this part. > Okay, note that similar handling would be required at other places like deparse_ColumnDef. Few other comments on v9-0001-Functions-to-deparse-DDL-commands. 1. +static ObjElem *new_bool_object(bool value); +static ObjElem *new_string_object(char *value); +static ObjElem *new_object_object(ObjTree *value); +static ObjElem *new_array_object(List *array); +static ObjElem *new_integer_object(int64 value); +static ObjElem *new_float_object(float8 value); Here, new_object_object() seems to be declared out-of-order (not in sync with its order of definition). Similarly, see all other append_* functions. 2. The function printTypmod in ddl_deparse.c appears to be the same as the function with the same name in format_type.c. If so, isn't it better to have a single copy of that function? 3. As I pointed out yesterday, there is some similarity between format_type_extended and format_type_detailed. Can we try to extract common functionality? If this is feasible, it is better to do this as a separate patch. Also, this can obviate the need to expose printTypmod from format_type.c. I am not really sure if this will be better than the current one or not but it seems worth trying. 4. new_objtree_VA() { ... switch (type) + { + case ObjTypeBool: + elem = new_bool_object(va_arg(args, int)); + break; + case ObjTypeString: + elem = new_string_object(va_arg(args, char *)); + break; + case ObjTypeObject: + elem = new_object_object(va_arg(args, ObjTree *)); + break; + case ObjTypeArray: + elem = new_array_object(va_arg(args, List *)); + break; + case ObjTypeInteger: + elem = new_integer_object(va_arg(args, int64)); + break; + case ObjTypeFloat: + elem = new_float_object(va_arg(args, double)); + break; + case ObjTypeNull: + /* Null params don't have a value (obviously) */ + elem = new_null_object(); ... I feel here ObjType's should be handled in the same order as they are defined in ObjType. 5. There appears to be common code among node_*_object() functions. Can we just have one function instead new_object(ObjType, void *val)? In the function based on type, we can typecast the value. Is there a reason why that won't be better than current one? 6. deparse_ColumnDef() { ... /* Composite types use a slightly simpler format string */ + if (composite) + column = new_objtree_VA("%{name}I %{coltype}T %{collation}s", + 3, + "type", ObjTypeString, "column", + "name", ObjTypeString, coldef->colname, + "coltype", ObjTypeObject, + new_objtree_for_type(typid, typmod)); + else + column = new_objtree_VA("%{name}I %{coltype}T %{default}s %{not_null}s %{collation}s", + 3, + "type", ObjTypeString, "column", + "name", ObjTypeString, coldef->colname, + "coltype", ObjTypeObject, + new_objtree_for_type(typid, typmod)); ... } To avoid using the same arguments, we can define fmtstr for composite and non-composite types as the patch is doing in deparse_CreateStmt(). 7. It is not clear from comments or otherwise what should be considered for default format string in functions like deparse_ColumnDef() or deparse_CreateStmt(). 8. + * FIXME --- actually, what about default values? + */ +static ObjTree * +deparse_ColumnDef_typed(Relation relation, List *dpcontext, ColumnDef *coldef) I think we need to handle default values for this FIXME. -- With Regards, Amit Kapila.