Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wKri0-001MEU-2r for pgsql-hackers@arkaria.postgresql.org; Thu, 07 May 2026 05:55:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wKrhy-002Apa-1Z for pgsql-hackers@arkaria.postgresql.org; Thu, 07 May 2026 05:55:38 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wKrhx-002Ap7-2M for pgsql-hackers@lists.postgresql.org; Thu, 07 May 2026 05:55:38 +0000 Received: from mail-pl1-x634.google.com ([2607:f8b0:4864:20::634]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wKrhu-00000000b6h-2HFA for pgsql-hackers@lists.postgresql.org; Thu, 07 May 2026 05:55:36 +0000 Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-2b9fcf7c91bso4573365ad.0 for ; Wed, 06 May 2026 22:55:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778133334; x=1778738134; darn=lists.postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=dXZmwjVdeLdePojC5R/QGje2owXgDWFBKXfLuCZJZc8=; b=VAQ+v1QuzF3FJLG2ZLXq0FaWvY4DpiHbL8LTskv0vjkcVBwifhRahQeVTQbzYByjjh pojcvMXWeSZOiG0I4pP6bIbwxKElRNWNG54lb93G4G1fK1XhlNbOyT81Q5536R0RA+PN Wo/6HDbkfR90doGp1e9Nt6d5l77XltX8qd7RBTANxr994Wf1q2JiQ0BbKD/niJuKzkz1 sni3F3Tp1Vv5V0QzUrqntxj2F8XYjErfaYz/kHXEM6pZgo1osIrjcY5MkSlaEOGcUoTp 8BHr5YSjW8Q747cUIXEH0dildgle/tRG7Ay9bjvFWSvyWKNo54lfmw4jAilqrWVNL+0k AwKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778133334; x=1778738134; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=dXZmwjVdeLdePojC5R/QGje2owXgDWFBKXfLuCZJZc8=; b=MlxLHsR1gneAdLq5oMjEstHsIwqWMArMr12Y/0h/yNzb3GT1Xh8YR4CTEiOAfNflMx Wpo9h9c13s1BmiM3DCNuG6XQv37bmp2UY3tp+d7QI9rfyj4vVXmbOCCU1PBL9iBBHDkU FkRJLDp7zAG5pOYdQyS+AP15kZDoT0dfqSxUUwv8TvQp9suOAo4Dh0i1yjFaRHBJv3kb ry/Nt7Xafwqm/+XmfMskmxRg5L2B5OCQ2lksbNSKUot55KZGsRazxwavSOtJm0PVMfz3 tufRJNcBLD6h9OEkSDulB5OBj5b0uJQteXmrJ7w+nhGLLR8nzbxzPqQVRmybMcFQX+Xi ahaA== X-Forwarded-Encrypted: i=1; AFNElJ8t53LGsWGhM5JTq9tiVnZThtGAPQfyMJ19BBvGVTLSQbp6yjJG6B2FB1kLcCra7Lsmh9avfemxBq1GEk7x@lists.postgresql.org X-Gm-Message-State: AOJu0Yw7/xacoFuBKBJs6srE6bPU/D5pETeUSxA3sh6SzlW7YRFCIPmo KxfR8qFafotYVPtOM7T7FdbL9vGsZFtY98XBweUbW+F23xM5lqJ2aZwf X-Gm-Gg: AeBDievLJELtz9AYPqzHYweESVg09cfH0wX51TNqfhKZcZqsQCi2szSTT/qJkxtTkMl Jz3Btrs7WxPp2+1/Qt+g5MXV0nQRs+XH7fu2Jn/ULGX3RQXU4KY5q1JibTFUW6BroMg7y+Yizj4 2oVPsOWLrGRgOezz9ACAaBi5NPh0xjyDQlIuTgZlgX8G492Z9upkahrURaMLsyjZu7qByqfkHsI dh/ziXkl+ZNSaeO9TYcbJro85xYbj1on2BGbsvalxCaqpMIbCqiY7f2vZLJgkJa4O8W3VrsoCi+ e4vTvkqZEjFBTPwt/6IAufzzDq+zs7Xsk/GjdY9BHGsq3U616C0aDGKKvNZ8x2tI0qsI8E4oc8I S8qczXte/yx+QwJKfd4XmsqSiIKQrku0Q9G0r0qTlH/qaMYyTHKnm8/M2Cr5psDngnWX2B1KC7a FxqZCfC3rnHi3Sony4t3FKt0bAv+420P7At0oKrhnsfg== X-Received: by 2002:a17:903:4b50:b0:2ba:a7f4:15b2 with SMTP id d9443c01a7336-2baa7f41d17mr37171945ad.39.1778133333998; Wed, 06 May 2026 22:55:33 -0700 (PDT) Received: from smtpclient.apple ([45.32.121.103]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2babaaf50e0sm11321075ad.33.2026.05.06.22.55.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 May 2026 22:55:32 -0700 (PDT) From: Chao Li Message-Id: <66C1555B-CA54-4ED1-AB4F-0EE97D24A006@gmail.com> Content-Type: multipart/mixed; boundary="Apple-Mail=_69E186E3-7BA3-4F0D-AF51-377E8FE410AB" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3864.400.21\)) Subject: Re: FOR PORTION OF does not recompute GENERATED STORED columns that depend on the range column Date: Thu, 7 May 2026 13:54:52 +0800 In-Reply-To: <27BD5D23-19C9-4FD1-8935-9C788C3C9869@gmail.com> Cc: Peter Eisentraut , jian he , SATYANARAYANA NARLAPURAM , PostgreSQL Hackers To: Paul A Jungwirth References: <27BD5D23-19C9-4FD1-8935-9C788C3C9869@gmail.com> X-Mailer: Apple Mail (2.3864.400.21) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_69E186E3-7BA3-4F0D-AF51-377E8FE410AB Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On May 7, 2026, at 12:34, Chao Li wrote: >=20 >=20 >=20 >> On May 7, 2026, at 01:13, Paul A Jungwirth = wrote: >>=20 >> On Wed, May 6, 2026 at 4:39=E2=80=AFAM Peter Eisentraut = wrote: >>>=20 >>> On 05.05.26 23:50, Paul A Jungwirth wrote: >>>> On Wed, Apr 22, 2026 at 11:03=E2=80=AFAM Paul A Jungwirth >>>> wrote: >>>>>=20 >>>>> Good catch! I removed that line in v7 (attached). I also included = your >>>>> test change to compute the range len by hand. Also a rebase was >>>>> necessary after d3bba04154. >>>>=20 >>>> This needed a rebase. v8 attached. >>>=20 >>> This patch fails the injection_points/isolation test for me. It = looks >>> like it causes a server crash. Check please. >>=20 >> Sorry, I didn't have injection_points enabled, but now I see it too. >> The attached v9 fixes it. >>=20 >> Yours, >>=20 >> --=20 >> Paul ~{:-) >> pj@illuminatedcomputing.com >> >=20 > Hi Paul, >=20 > I didn=E2=80=99t review this patch earlier because, from the subject, = I thought it was only about recomputing generated stored columns. I just = noticed that the patch also changes the inheritance-table path, and I = posted another patch for the inheritance-table bug. Please see [1]. >=20 > I tried applying the new tests from my patch on top of this patch, and = it looks like this patch still does not fix the multi-inheritance case. >=20 > So I=E2=80=99d like to check with you how we should proceed. I think = there are two options: >=20 > 1. Keep this patch focused on the generated-column issue described in = the subject, and use my patch to fix the inheritance-table bug. > 2. I can continue from this patch and extend it to fix the = multi-inheritance case as well. >=20 > Please let me know what you prefer. >=20 > [1] = https://www.postgresql.org/message-id/4245F94D-84F1-4E05-BF81-C458A6CF9901= %40gmail.com >=20 I just looked into v9 and made a fix in ExecInitForPortionOf() that = resolves the bug with multi-inheritance tables. I also added a test case = for that. The inheritance-table bug affects not only UPDATE, but also DELETE, so I = added test cases for DELETE as well. Please see 0002 for my changes. To make each commit self-contained, would you mind moving the code for = the inheritance-table fix to 0002? Then you can keep focusing on 0001, = and I can continue working on 0002. PFA v10 - 0001 the same as v9. 0002 fixed a bug with multi-inheritance = tables. (Note, in 0002, there is a comment format change around line 1496, that = was done by pgindent.) Best regards, -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_69E186E3-7BA3-4F0D-AF51-377E8FE410AB Content-Disposition: attachment; filename=v10-0001-Fix-some-problems-with-UPDATE-FOR-PORTION-OF.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v10-0001-Fix-some-problems-with-UPDATE-FOR-PORTION-OF.patch" Content-Transfer-Encoding: quoted-printable =46rom=20c98f20a41f10fd357f5c4d162a95d995bbc8feda=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20jian=20he=20=0A= Date:=20Fri,=2010=20Apr=202026=2017:01:12=20+0800=0ASubject:=20[PATCH=20= v10=201/2]=20Fix=20some=20problems=20with=20UPDATE=20FOR=20PORTION=20OF=0A= =0A-=20Fixed=20inserting=20leftovers=20with=20traditional=20table=20= inheritance.=20Since=20there=20is=0A=20=20no=20tuple=20routing,=20we=20= must=20add=20them=20directly=20to=20the=20child=20table.=20Also=20this=0A= =20=20preserves=20extra=20columns=20in=20that=20table.=0A-=20Added=20= ExecInitForPortionOf.=20This=20sets=20up=20executor=20state=20for=20= child=20partitions.=0A=20=20Previously=20we=20did=20this=20in=20= ExecForPortionOfLeftovers,=20but=20doing=20it=20earlier=20lets=0A=20=20= us=20use=20the=20child->parent=20attr=20mapping=20in=20the=20fixes=20= below.=0A-=20Made=20sure=20GENERATED=20STORED=20columns=20that=20depend=20= on=20the=20application-time=20column=0A=20=20get=20updated.=20We=20= exclude=20that=20column=20from=20the=20updatedCols=20bitmapset,=20= because=20it=0A=20=20does=20not=20require=20permissions.=20But=20then=20= we=20must=20remember=20to=20add=20it=20later.=20This=0A=20=20also=20= fixes=20a=20similar=20problem=20with=20UPDATE=20OF=20triggers.=0A-=20= Clarified=20a=20comment=20about=20the=20rangetype=20stored=20in=20= ForPortionOfState.=0A=0ADiscussion:=20= https://postgr.es/m/CAHg+QDcd=3Dt69gLf9yQexO07EJ2mx0Z70NFHo6h94X1EDA=3DhM0= g@mail.gmail.com=0ADiscussion:=20= https://postgr.es/m/CAHg+QDcsXsUVaZ+JwM02yDRQEi=3DcL_rTH_ROLDYgOx004sQu7A@= mail.gmail.com=0A---=0A=20src/backend/executor/execUtils.c=20=20=20=20=20= =20=20=20=20=20=20=20=20|=20=2036=20++-=0A=20= src/backend/executor/nodeModifyTable.c=20=20=20=20=20=20=20|=20145=20= ++++++++----=0A=20src/include/nodes/execnodes.h=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20|=20=20=203=20+-=0A=20= src/test/regress/expected/for_portion_of.out=20|=20221=20= +++++++++++++++----=0A=20src/test/regress/sql/for_portion_of.sql=20=20=20= =20=20=20|=20=2094=20+++++++-=0A=205=20files=20changed,=20400=20= insertions(+),=2099=20deletions(-)=0A=0Adiff=20--git=20= a/src/backend/executor/execUtils.c=20b/src/backend/executor/execUtils.c=0A= index=201eb6b9f1f40..ae23c248081=20100644=0A---=20= a/src/backend/executor/execUtils.c=0A+++=20= b/src/backend/executor/execUtils.c=0A@@=20-1408,20=20+1408,52=20@@=20= Bitmapset=20*=0A=20ExecGetUpdatedCols(ResultRelInfo=20*relinfo,=20EState=20= *estate)=0A=20{=0A=20=09RTEPermissionInfo=20*perminfo=20=3D=20= GetResultRTEPermissionInfo(relinfo,=20estate);=0A+=09Bitmapset=20= *updatedCols;=0A=20=0A=20=09if=20(perminfo=20=3D=3D=20NULL)=0A=20=09=09= return=20NULL;=0A=20=0A+=09updatedCols=20=3D=20perminfo->updatedCols;=0A= +=0A=20=09/*=20Map=20the=20columns=20to=20child's=20attribute=20numbers=20= if=20needed.=20*/=0A=20=09if=20(relinfo->ri_RootResultRelInfo)=0A=20=09{=0A= =20=09=09TupleConversionMap=20*map=20=3D=20= ExecGetRootToChildMap(relinfo,=20estate);=0A=20=0A=20=09=09if=20(map)=0A= -=09=09=09return=20execute_attr_map_cols(map->attrMap,=20= perminfo->updatedCols);=0A+=09=09=09updatedCols=20=3D=20= execute_attr_map_cols(map->attrMap,=20updatedCols);=0A+=09}=0A+=0A+=09/*=0A= +=09=20*=20For=20UPDATE=20...=20FOR=20PORTION=20OF,=20the=20range=20= column=20is=20being=20modified=0A+=09=20*=20(narrowed=20via=20= intersection),=20but=20it=20is=20not=20included=20in=20updatedCols=0A+=09= =20*=20because=20the=20user=20does=20not=20need=20UPDATE=20permission=20= on=20it.=20Now=20manualy=0A+=09=20*=20add=20it=20to=20updatedCols.=20= Since=20ri_forPortionOf->fp_rangeAttno=20is=20already=0A+=09=20*=20= mapped=20for=20the=20child=20partition,=20we=20have=20to=20add=20it=20= after=20the=20mapping=20just=0A+=09=20*=20above.=20Also=20that=20makes=20= it=20unsafe=20to=20mutate=20perminfo.=20XXX:=20Always=20add=20the=0A+=09=20= *=20unmapped=20attno=20instead=20(before=20mapping),=20and=20mutate=20= perminfo,=20to=20avoid=0A+=09=20*=20repeated=20allocations?=0A+=09=20*/=0A= +=09if=20(relinfo->ri_forPortionOf)=0A+=09{=0A+=09=09AttrNumber=09= rangeAttno=20=3D=20relinfo->ri_forPortionOf->fp_rangeAttno;=0A+=0A+=09=09= if=20(!bms_is_member(rangeAttno=20-=20= FirstLowInvalidHeapAttributeNumber,=0A+=09=09=09=09=09=09=20=20=20= updatedCols))=0A+=09=09{=0A+=09=09=09MemoryContext=20oldContext;=0A+=0A+=09= =09=09oldContext=20=3D=20MemoryContextSwitchTo(estate->es_query_cxt);=0A= +=0A+=09=09=09updatedCols=20=3D=0A+=09=09=09=09= bms_add_member(updatedCols,=0A+=09=09=09=09=09=09=09=20=20=20rangeAttno=20= -=20FirstLowInvalidHeapAttributeNumber);=0A+=0A+=09=09=09= MemoryContextSwitchTo(oldContext);=0A+=09=09}=0A=20=09}=0A=20=0A-=09= return=20perminfo->updatedCols;=0A+=09return=20updatedCols;=0A=20}=0A=20=0A= =20/*=20Return=20a=20bitmap=20representing=20generated=20columns=20being=20= updated=20*/=0Adiff=20--git=20a/src/backend/executor/nodeModifyTable.c=20= b/src/backend/executor/nodeModifyTable.c=0Aindex=20= 4cb057ca4f9..81f5afc9fb7=20100644=0A---=20= a/src/backend/executor/nodeModifyTable.c=0A+++=20= b/src/backend/executor/nodeModifyTable.c=0A@@=20-198,6=20+198,8=20@@=20= static=20TupleTableSlot=20*ExecMergeNotMatched(ModifyTableContext=20= *context,=0A=20static=20void=20= ExecSetupTransitionCaptureState(ModifyTableState=20*mtstate,=20EState=20= *estate);=0A=20static=20void=20fireBSTriggers(ModifyTableState=20*node);=0A= =20static=20void=20fireASTriggers(ModifyTableState=20*node);=0A+static=20= void=20ExecInitForPortionOf(ModifyTableState=20*mtstate,=20EState=20= *estate,=0A+=09=09=09=09=09=09=09=09=20ResultRelInfo=20*resultRelInfo);=0A= =20=0A=20=0A=20/*=0A@@=20-1409,7=20+1411,6=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09= ModifyTableState=20*mtstate=20=3D=20context->mtstate;=0A=20=09= ModifyTable=20*node=20=3D=20(ModifyTable=20*)=20mtstate->ps.plan;=0A=20=09= ForPortionOfExpr=20*forPortionOf=20=3D=20(ForPortionOfExpr=20*)=20= node->forPortionOf;=0A-=09AttrNumber=09rangeAttno;=0A=20=09Datum=09=09= oldRange;=0A=20=09TypeCacheEntry=20*typcache;=0A=20=09ForPortionOfState=20= *fpoState;=0A@@=20-1424,37=20+1425,10=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09= ReturnSetInfo=20rsi;=0A=20=09bool=09=09didInit=20=3D=20false;=0A=20=09= bool=09=09shouldFree=20=3D=20false;=0A+=09ResultRelInfo=20*rootRelInfo=20= =3D=20mtstate->rootResultRelInfo;=0A=20=0A=20=09LOCAL_FCINFO(fcinfo,=20= 2);=0A=20=0A-=09if=20(!resultRelInfo->ri_forPortionOf)=0A-=09{=0A-=09=09= /*=0A-=09=09=20*=20If=20we=20don't=20have=20a=20ForPortionOfState=20yet,=20= we=20must=20be=20a=20partition=0A-=09=09=20*=20child=20being=20hit=20for=20= the=20first=20time.=20Make=20a=20copy=20from=20the=20root,=20with=0A-=09=09= =20*=20our=20own=20TupleTableSlot.=20We=20do=20this=20lazily=20so=20that=20= we=20don't=20pay=20the=0A-=09=09=20*=20price=20of=20unused=20partitions.=0A= -=09=09=20*/=0A-=09=09ForPortionOfState=20*leafState=20=3D=20= makeNode(ForPortionOfState);=0A-=0A-=09=09if=20= (!mtstate->rootResultRelInfo)=0A-=09=09=09elog(ERROR,=20"no=20root=20= relation=20but=20ri_forPortionOf=20is=20uninitialized");=0A-=0A-=09=09= fpoState=20=3D=20mtstate->rootResultRelInfo->ri_forPortionOf;=0A-=09=09= Assert(fpoState);=0A-=0A-=09=09leafState->fp_rangeName=20=3D=20= fpoState->fp_rangeName;=0A-=09=09leafState->fp_rangeType=20=3D=20= fpoState->fp_rangeType;=0A-=09=09leafState->fp_rangeAttno=20=3D=20= fpoState->fp_rangeAttno;=0A-=09=09leafState->fp_targetRange=20=3D=20= fpoState->fp_targetRange;=0A-=09=09leafState->fp_Leftover=20=3D=20= fpoState->fp_Leftover;=0A-=09=09/*=20Each=20partition=20needs=20a=20slot=20= matching=20its=20tuple=20descriptor=20*/=0A-=09=09leafState->fp_Existing=20= =3D=0A-=09=09=09table_slot_create(resultRelInfo->ri_RelationDesc,=0A-=09=09= =09=09=09=09=09=20=20&mtstate->ps.state->es_tupleTable);=0A-=0A-=09=09= resultRelInfo->ri_forPortionOf=20=3D=20leafState;=0A-=09}=0A=20=09= fpoState=20=3D=20resultRelInfo->ri_forPortionOf;=0A=20=09oldtupleSlot=20= =3D=20fpoState->fp_Existing;=0A=20=09leftoverSlot=20=3D=20= fpoState->fp_Leftover;=0A@@=20-1475,21=20+1449,13=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09if=20= (!table_tuple_fetch_row_version(resultRelInfo->ri_RelationDesc,=20= tupleid,=20SnapshotAny,=20oldtupleSlot))=0A=20=09=09elog(ERROR,=20= "failed=20to=20fetch=20tuple=20for=20FOR=20PORTION=20OF");=0A=20=0A-=09= /*=0A-=09=20*=20Get=20the=20old=20range=20of=20the=20record=20being=20= updated/deleted.=20Must=20read=20with=0A-=09=20*=20the=20attno=20of=20= the=20leaf=20partition=20being=20updated.=0A-=09=20*/=0A-=0A-=09= rangeAttno=20=3D=20forPortionOf->rangeVar->varattno;=0A-=09if=20= (resultRelInfo->ri_RootResultRelInfo)=0A-=09=09map=20=3D=20= ExecGetChildToRootMap(resultRelInfo);=0A-=09if=20(map=20!=3D=20NULL)=0A-=09= =09rangeAttno=20=3D=20map->attrMap->attnums[rangeAttno=20-=201];=0A=20=09= slot_getallattrs(oldtupleSlot);=0A=20=0A-=09if=20= (oldtupleSlot->tts_isnull[rangeAttno=20-=201])=0A+=09/*=20Get=20the=20= old=20range=20of=20the=20record=20being=20updated/deleted.=20*/=0A+=0A+=09= if=20(oldtupleSlot->tts_isnull[fpoState->fp_rangeAttno=20-=201])=0A=20=09= =09elog(ERROR,=20"found=20a=20NULL=20range=20in=20a=20temporal=20= table");=0A-=09oldRange=20=3D=20oldtupleSlot->tts_values[rangeAttno=20-=20= 1];=0A+=09oldRange=20=3D=20= oldtupleSlot->tts_values[fpoState->fp_rangeAttno=20-=201];=0A=20=0A=20=09= /*=0A=20=09=20*=20Get=20the=20range's=20type=20cache=20entry.=20This=20= is=20worth=20caching=20for=20the=20whole=0A@@=20-1527,12=20+1493,20=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09= fcinfo->args[1].isnull=20=3D=20false;=0A=20=0A=20=09/*=0A-=09=20*=20If=20= there=20are=20partitions,=20we=20must=20insert=20into=20the=20root=20= table,=20so=20we=20get=0A-=09=20*=20tuple=20routing.=20We=20already=20= set=20up=20leftoverSlot=20with=20the=20root=20tuple=0A-=09=20*=20= descriptor.=0A+=09=20*=20For=20partitioned=20tables,=20we=20must=20read=20= leftovers=20with=20the=20tuple=20descriptor=0A+=09=20*=20of=20the=20= child=20table,=20but=20insert=20into=20the=20root=20table=20to=20enable=20= tuple=0A+=09=20*=20routing.=20=20So=20leftoverSlot=20is=20configured=20= with=20the=20root's=20tuple=0A+=09=20*=20descriptor.=20=20However,=20for=20= traditional=20table=20inheritance,=20we=20don't=20need=0A+=09=20*=20= tuple=20routing=20and=20just=20insert=20directly=20into=20the=20child=20= table=20to=20preserve=0A+=09=20*=20child-specific=20columns.=20=20In=20= that=20case,=20leftoverSlot=20uses=20the=20child's=0A+=09=20*=20= (resultRelInfo)=20tuple=20descriptor.=0A=20=09=20*/=0A-=09if=20= (resultRelInfo->ri_RootResultRelInfo)=0A+=09if=20(rootRelInfo=20&&=0A+=09= =09rootRelInfo->ri_RelationDesc->rd_rel->relkind=20=3D=3D=20= RELKIND_PARTITIONED_TABLE)=0A+=09{=0A+=09=09map=20=3D=20= ExecGetChildToRootMap(resultRelInfo);=0A=20=09=09resultRelInfo=20=3D=20= resultRelInfo->ri_RootResultRelInfo;=0A+=09}=0A=20=0A=20=09/*=0A=20=09=20= *=20Insert=20a=20leftover=20for=20each=20value=20returned=20by=20the=20= without_portion=20helper=0A@@=20-1601,8=20+1575,9=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09=09=09= didInit=20=3D=20true;=0A=20=09=09}=0A=20=0A-=09=09= leftoverSlot->tts_values[forPortionOf->rangeVar->varattno=20-=201]=20=3D=20= leftover;=0A-=09=09= leftoverSlot->tts_isnull[forPortionOf->rangeVar->varattno=20-=201]=20=3D=20= false;=0A+=09=09= leftoverSlot->tts_values[resultRelInfo->ri_forPortionOf->fp_rangeAttno=20= -=201]=20=3D=20leftover;=0A+=09=09= leftoverSlot->tts_isnull[resultRelInfo->ri_forPortionOf->fp_rangeAttno=20= -=201]=20=3D=20false;=0A+=0A=20=09=09ExecMaterializeSlot(leftoverSlot);=0A= =20=0A=20=09=09/*=0A@@=20-4777,6=20+4752,18=20@@=20= ExecModifyTable(PlanState=20*pstate)=0A=20=09=09=09=09=09=09=09=09=09=09=09= =09=09=09=20false,=20true);=0A=20=09=09}=0A=20=0A+=09=09/*=0A+=09=09=20*=20= If=20we=20don't=20have=20a=20ForPortionOfState=20yet,=20we=20must=20be=20= a=20partition=0A+=09=09=20*=20child=20being=20hit=20for=20the=20first=20= time.=20Make=20a=20copy=20from=20the=20root,=20with=0A+=09=09=20*=20our=20= own=20TupleTableSlot.=20We=20do=20this=20lazily=20so=20that=20we=20don't=20= pay=20the=0A+=09=09=20*=20price=20of=20unused=20partitions.=0A+=09=09=20= */=0A+=09=09if=20((((ModifyTable=20*)=20= context.mtstate->ps.plan)->forPortionOf)=20&&=0A+=09=09=09= !resultRelInfo->ri_forPortionOf)=0A+=09=09{=0A+=09=09=09= ExecInitForPortionOf(context.mtstate,=20estate,=20resultRelInfo);=0A+=09=09= }=0A+=0A=20=09=09/*=0A=20=09=09=20*=20If=20= resultRelInfo->ri_usesFdwDirectModify=20is=20true,=20all=20we=20need=20= to=20do=0A=20=09=09=20*=20here=20is=20compute=20the=20RETURNING=20= expressions.=0A@@=20-5860,3=20+5847,67=20@@=20= ExecReScanModifyTable(ModifyTableState=20*node)=0A=20=09=20*/=0A=20=09= elog(ERROR,=20"ExecReScanModifyTable=20is=20not=20implemented");=0A=20}=0A= +=0A+/*=20= ----------------------------------------------------------------=0A+=20*=09= =09ExecInitForPortionOf=0A+=20*=0A+=20*=09=09Initializes=20= resultRelInfo->ri_forPortionOf=20for=20child=20tables.=0A+=20*=20= ----------------------------------------------------------------=0A+=20= */=0A+static=20void=0A+ExecInitForPortionOf(ModifyTableState=20*mtstate,=20= EState=20*estate,=20ResultRelInfo=20*resultRelInfo)=0A+{=0A+=09= MemoryContext=20oldcxt;=0A+=09ForPortionOfState=20*leafState;=0A+=09= ResultRelInfo=20*rootRelInfo=20=3D=20mtstate->rootResultRelInfo;=0A+=09= ForPortionOfState=20*fpoState;=0A+=0A+=09if=20(!rootRelInfo)=0A+=09=09= elog(ERROR,=20"no=20root=20relation=20but=20ri_forPortionOf=20is=20= uninitialized");=0A+=0A+=09fpoState=20=3D=20= mtstate->rootResultRelInfo->ri_forPortionOf;=0A+=0A+=09/*=20Things=20= built=20here=20have=20to=20last=20for=20the=20query=20duration.=20*/=0A+=09= oldcxt=20=3D=20MemoryContextSwitchTo(estate->es_query_cxt);=0A+=0A+=09= leafState=20=3D=20makeNode(ForPortionOfState);=0A+=0A+=09= leafState->fp_rangeName=20=3D=20fpoState->fp_rangeName;=0A+=09= leafState->fp_rangeType=20=3D=20fpoState->fp_rangeType;=0A+=09= leafState->fp_targetRange=20=3D=20fpoState->fp_targetRange;=0A+=0A+=09/*=0A= +=09=20*=20For=20partitioned=20tables=20we=20must=20read=20the=20= leftovers=20using=20the=20child=20table's=0A+=09=20*=20tuple=20= descriptor,=20but=20then=20insert=20them=20into=20the=20root=20table=20= (using=20its=0A+=09=20*=20tuple=20descriptor)=20so=20we=20get=20tuple=20= routing.=0A+=09=20*=0A+=09=20*=20For=20traditional=20table=20= inheritance,=20we=20read=20and=20insert=20directly=20into=20this=0A+=09=20= *=20resultRelInfo;=20no=20tuple=20routing=20to=20the=20parent=20is=20= required.=0A+=09=20*/=0A+=09if=20= (rootRelInfo->ri_RelationDesc->rd_rel->relkind=20=3D=3D=20= RELKIND_PARTITIONED_TABLE)=0A+=09{=0A+=09=09TupleConversionMap=20*map=20= =3D=20ExecGetChildToRootMap(resultRelInfo);=0A+=09=09if=20(map)=0A+=09=09= =09leafState->fp_rangeAttno=20=3D=20= map->attrMap->attnums[fpoState->fp_rangeAttno=20-=201];=0A+=09=09else=0A= +=09=09=09leafState->fp_rangeAttno=20=3D=20fpoState->fp_rangeAttno;=0A+=09= =09leafState->fp_Leftover=20=3D=20fpoState->fp_Leftover;=0A+=09}=0A+=09= else=0A+=09{=0A+=09=09leafState->fp_rangeAttno=20=3D=20= fpoState->fp_rangeAttno;=0A+=09=09leafState->fp_Leftover=20=3D=0A+=09=09=09= ExecInitExtraTupleSlot(mtstate->ps.state,=0A+=09=09=09=09=09=09=09=09=20=20= =20RelationGetDescr(resultRelInfo->ri_RelationDesc),=0A+=09=09=09=09=09=09= =09=09=20=20=20&TTSOpsVirtual);=0A+=09}=0A+=0A+=09/*=20Each=20partition=20= needs=20a=20slot=20matching=20its=20tuple=20descriptor=20*/=0A+=09= leafState->fp_Existing=20=3D=0A+=09=09= table_slot_create(resultRelInfo->ri_RelationDesc,=0A+=09=09=09=09=09=09=20= =20&mtstate->ps.state->es_tupleTable);=0A+=0A+=09= resultRelInfo->ri_forPortionOf=20=3D=20leafState;=0A+=0A+=09= MemoryContextSwitchTo(oldcxt);=0A+}=0Adiff=20--git=20= a/src/include/nodes/execnodes.h=20b/src/include/nodes/execnodes.h=0A= index=2013359180d25..53c138310db=20100644=0A---=20= a/src/include/nodes/execnodes.h=0A+++=20b/src/include/nodes/execnodes.h=0A= @@=20-477,7=20+477,8=20@@=20typedef=20struct=20ForPortionOfState=0A=20=09= NodeTag=09=09type;=0A=20=0A=20=09char=09=20=20=20*fp_rangeName;=09/*=20= the=20column=20named=20in=20FOR=20PORTION=20OF=20*/=0A-=09Oid=09=09=09= fp_rangeType;=09/*=20the=20type=20of=20the=20FOR=20PORTION=20OF=20= expression=20*/=0A+=09Oid=09=09=09fp_rangeType;=09/*=20the=20base=20type=20= (not=20domain)=20of=20the=20FOR=0A+=09=09=09=09=09=09=09=09=20*=20= PORTION=20OF=20expression=20*/=0A=20=09int=09=09=09fp_rangeAttno;=09/*=20= the=20attno=20of=20the=20range=20column=20*/=0A=20=09Datum=09=09= fp_targetRange;=20/*=20the=20range/multirange=20from=20FOR=20PORTION=20= OF=20*/=0A=20=09TypeCacheEntry=20*fp_leftoverstypcache;=09/*=20type=20= cache=20entry=20of=20the=20range=20*/=0Adiff=20--git=20= a/src/test/regress/expected/for_portion_of.out=20= b/src/test/regress/expected/for_portion_of.out=0Aindex=20= 0c0a205c44b..91241463991=20100644=0A---=20= a/src/test/regress/expected/for_portion_of.out=0A+++=20= b/src/test/regress/expected/for_portion_of.out=0A@@=20-1365,6=20+1365,9=20= @@=20$$;=0A=20CREATE=20TRIGGER=20fpo_before_stmt=0A=20=20=20BEFORE=20= INSERT=20OR=20UPDATE=20OR=20DELETE=20ON=20for_portion_of_test=0A=20=20=20= FOR=20EACH=20STATEMENT=20EXECUTE=20PROCEDURE=20dump_trigger(false,=20= false);=0A+CREATE=20TRIGGER=20fpo_before_stmt1=0A+=20=20BEFORE=20UPDATE=20= OF=20valid_at=20ON=20for_portion_of_test=0A+=20=20FOR=20EACH=20STATEMENT=20= EXECUTE=20PROCEDURE=20dump_trigger(false,=20false);=0A=20CREATE=20= TRIGGER=20fpo_after_insert_stmt=0A=20=20=20AFTER=20INSERT=20ON=20= for_portion_of_test=0A=20=20=20FOR=20EACH=20STATEMENT=20EXECUTE=20= PROCEDURE=20dump_trigger(false,=20false);=0A@@=20-1378,6=20+1381,9=20@@=20= CREATE=20TRIGGER=20fpo_after_delete_stmt=0A=20CREATE=20TRIGGER=20= fpo_before_row=0A=20=20=20BEFORE=20INSERT=20OR=20UPDATE=20OR=20DELETE=20= ON=20for_portion_of_test=0A=20=20=20FOR=20EACH=20ROW=20EXECUTE=20= PROCEDURE=20dump_trigger(false,=20false);=0A+CREATE=20TRIGGER=20= fpo_before_row1=0A+=20=20BEFORE=20UPDATE=20OF=20valid_at=20ON=20= for_portion_of_test=0A+=20=20FOR=20EACH=20ROW=20EXECUTE=20PROCEDURE=20= dump_trigger(false,=20false);=0A=20CREATE=20TRIGGER=20= fpo_after_insert_row=0A=20=20=20AFTER=20INSERT=20ON=20= for_portion_of_test=0A=20=20=20FOR=20EACH=20ROW=20EXECUTE=20PROCEDURE=20= dump_trigger(false,=20false);=0A@@=20-1394,9=20+1400,15=20@@=20UPDATE=20= for_portion_of_test=0A=20NOTICE:=20=20fpo_before_stmt:=20BEFORE=20UPDATE=20= STATEMENT:=0A=20NOTICE:=20=20=20=20old:=20=0A=20NOTICE:=20=20=20=20= new:=20=0A+NOTICE:=20=20fpo_before_stmt1:=20BEFORE=20UPDATE=20= STATEMENT:=0A+NOTICE:=20=20=20=20old:=20=0A+NOTICE:=20=20=20=20= new:=20=0A=20NOTICE:=20=20fpo_before_row:=20BEFORE=20UPDATE=20ROW:=0A= =20NOTICE:=20=20=20=20old:=20[2019-01-01,2030-01-01)=0A=20NOTICE:=20=20=20= =20new:=20[2021-01-01,2022-01-01)=0A+NOTICE:=20=20fpo_before_row1:=20= BEFORE=20UPDATE=20ROW:=0A+NOTICE:=20=20=20=20old:=20= [2019-01-01,2030-01-01)=0A+NOTICE:=20=20=20=20new:=20= [2021-01-01,2022-01-01)=0A=20NOTICE:=20=20fpo_before_stmt:=20BEFORE=20= INSERT=20STATEMENT:=0A=20NOTICE:=20=20=20=20old:=20=0A=20NOTICE:=20= =20=20=20new:=20=0A@@=20-1986,6=20+1998,7=20@@=20SELECT=20*=20FROM=20= for_portion_of_test2=20ORDER=20BY=20id,=20valid_at;=0A=20DROP=20TABLE=20= for_portion_of_test2;=0A=20DROP=20TYPE=20mydaterange;=0A=20--=20Test=20= FOR=20PORTION=20OF=20against=20a=20partitioned=20table.=0A+--=20Include=20= a=20GENERATED=20STORED=20column=20to=20test=20updatedCols=20column=20= mapping.=0A=20--=20temporal_partitioned_1=20has=20the=20same=20attnums=20= as=20the=20root=0A=20--=20temporal_partitioned_3=20has=20the=20different=20= attnums=20from=20the=20root=0A=20--=20temporal_partitioned_5=20has=20the=20= different=20attnums=20too,=20but=20reversed=0A@@=20-1993,29=20+2006,34=20= @@=20CREATE=20TABLE=20temporal_partitioned=20(=0A=20=20=20id=20= int4range,=0A=20=20=20valid_at=20daterange,=0A=20=20=20name=20text,=0A+=20= =20range_len=20int=20GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20= lower(valid_at))=20STORED,=0A=20=20=20CONSTRAINT=20= temporal_paritioned_uq=20UNIQUE=20(id,=20valid_at=20WITHOUT=20OVERLAPS)=0A= =20)=20PARTITION=20BY=20LIST=20(id);=0A=20CREATE=20TABLE=20= temporal_partitioned_1=20PARTITION=20OF=20temporal_partitioned=20FOR=20= VALUES=20IN=20('[1,2)',=20'[2,3)');=0A=20CREATE=20TABLE=20= temporal_partitioned_3=20PARTITION=20OF=20temporal_partitioned=20FOR=20= VALUES=20IN=20('[3,4)',=20'[4,5)');=0A=20CREATE=20TABLE=20= temporal_partitioned_5=20PARTITION=20OF=20temporal_partitioned=20FOR=20= VALUES=20IN=20('[5,6)',=20'[6,7)');=0A=20ALTER=20TABLE=20= temporal_partitioned=20DETACH=20PARTITION=20temporal_partitioned_3;=0A= -ALTER=20TABLE=20temporal_partitioned_3=20DROP=20COLUMN=20id,=20DROP=20= COLUMN=20valid_at;=0A+ALTER=20TABLE=20temporal_partitioned_3=20DROP=20= COLUMN=20id,=20DROP=20COLUMN=20valid_at=20CASCADE;=0A+NOTICE:=20=20drop=20= cascades=20to=20column=20range_len=20of=20table=20temporal_partitioned_3=0A= =20ALTER=20TABLE=20temporal_partitioned_3=20ADD=20COLUMN=20id=20= int4range=20NOT=20NULL,=20ADD=20COLUMN=20valid_at=20daterange=20NOT=20= NULL;=0A+ALTER=20TABLE=20temporal_partitioned_3=20ADD=20COLUMN=20= range_len=20int=20GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20= lower(valid_at))=20STORED;=0A=20ALTER=20TABLE=20temporal_partitioned=20= ATTACH=20PARTITION=20temporal_partitioned_3=20FOR=20VALUES=20IN=20= ('[3,4)',=20'[4,5)');=0A=20ALTER=20TABLE=20temporal_partitioned=20DETACH=20= PARTITION=20temporal_partitioned_5;=0A-ALTER=20TABLE=20= temporal_partitioned_5=20DROP=20COLUMN=20id,=20DROP=20COLUMN=20valid_at;=0A= +ALTER=20TABLE=20temporal_partitioned_5=20DROP=20COLUMN=20id,=20DROP=20= COLUMN=20valid_at=20CASCADE;=0A+NOTICE:=20=20drop=20cascades=20to=20= column=20range_len=20of=20table=20temporal_partitioned_5=0A=20ALTER=20= TABLE=20temporal_partitioned_5=20ADD=20COLUMN=20valid_at=20daterange=20= NOT=20NULL,=20ADD=20COLUMN=20id=20int4range=20NOT=20NULL;=0A+ALTER=20= TABLE=20temporal_partitioned_5=20ADD=20COLUMN=20range_len=20int=20= GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20lower(valid_at))=20= STORED;=0A=20ALTER=20TABLE=20temporal_partitioned=20ATTACH=20PARTITION=20= temporal_partitioned_5=20FOR=20VALUES=20IN=20('[5,6)',=20'[6,7)');=0A=20= INSERT=20INTO=20temporal_partitioned=20(id,=20valid_at,=20name)=20VALUES=0A= =20=20=20('[1,2)',=20daterange('2000-01-01',=20'2010-01-01'),=20'one'),=0A= =20=20=20('[3,4)',=20daterange('2000-01-01',=20'2010-01-01'),=20= 'three'),=0A=20=20=20('[5,6)',=20daterange('2000-01-01',=20= '2010-01-01'),=20'five');=0A=20SELECT=20*=20FROM=20temporal_partitioned;=0A= -=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20= =20|=20name=20=20=0A--------+-------------------------+-------=0A-=20= [1,2)=20|=20[2000-01-01,2010-01-01)=20|=20one=0A-=20[3,4)=20|=20= [2000-01-01,2010-01-01)=20|=20three=0A-=20[5,6)=20|=20= [2000-01-01,2010-01-01)=20|=20five=0A+=20=20id=20=20=20|=20=20=20=20=20=20= =20=20valid_at=20=20=20=20=20=20=20=20=20|=20name=20=20|=20range_len=20=0A= +-------+-------------------------+-------+-----------=0A+=20[1,2)=20|=20= [2000-01-01,2010-01-01)=20|=20one=20=20=20|=20=20=20=20=20=203653=0A+=20= [3,4)=20|=20[2000-01-01,2010-01-01)=20|=20three=20|=20=20=20=20=20=20= 3653=0A+=20[5,6)=20|=20[2000-01-01,2010-01-01)=20|=20five=20=20|=20=20=20= =20=20=203653=0A=20(3=20rows)=0A=20=0A=20--=20Update=20without=20moving=20= within=20partition=201=0A@@=20-2046,54=20+2064,54=20@@=20UPDATE=20= temporal_partitioned=20FOR=20PORTION=20OF=20valid_at=20FROM=20= '2000-06-01'=20TO=20'2000-0=0A=20=20=20=20=20=20=20id=20=3D=20'[3,4)'=0A=20= =20=20WHERE=20id=20=3D=20'[5,6)';=0A=20--=20Update=20all=20partitions=20= at=20once=20(each=20with=20leftovers)=0A-SELECT=20*=20FROM=20= temporal_partitioned=20ORDER=20BY=20id,=20valid_at;=0A-=20=20id=20=20=20= |=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20=20name=20= =20=20=0A--------+-------------------------+---------=0A-=20[1,2)=20|=20= [2000-01-01,2000-03-01)=20|=20one=0A-=20[1,2)=20|=20= [2000-03-01,2000-04-01)=20|=20one^1=0A-=20[1,2)=20|=20= [2000-04-01,2000-06-01)=20|=20one=0A-=20[1,2)=20|=20= [2000-07-01,2010-01-01)=20|=20one=0A-=20[2,3)=20|=20= [2000-06-01,2000-07-01)=20|=20three^2=0A-=20[3,4)=20|=20= [2000-01-01,2000-03-01)=20|=20three=0A-=20[3,4)=20|=20= [2000-03-01,2000-04-01)=20|=20three^1=0A-=20[3,4)=20|=20= [2000-04-01,2000-06-01)=20|=20three=0A-=20[3,4)=20|=20= [2000-06-01,2000-07-01)=20|=20five^2=0A-=20[3,4)=20|=20= [2000-07-01,2010-01-01)=20|=20three=0A-=20[4,5)=20|=20= [2000-06-01,2000-07-01)=20|=20one^2=0A-=20[5,6)=20|=20= [2000-01-01,2000-03-01)=20|=20five=0A-=20[5,6)=20|=20= [2000-03-01,2000-04-01)=20|=20five^1=0A-=20[5,6)=20|=20= [2000-04-01,2000-06-01)=20|=20five=0A-=20[5,6)=20|=20= [2000-07-01,2010-01-01)=20|=20five=0A+SELECT=20*,=20upper(valid_at)=20-=20= lower(valid_at)=20FROM=20temporal_partitioned=20ORDER=20BY=20id,=20= valid_at;=0A+=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20= =20=20=20=20=20|=20=20name=20=20=20|=20range_len=20|=20?column?=20=0A= +-------+-------------------------+---------+-----------+----------=0A+=20= [1,2)=20|=20[2000-01-01,2000-03-01)=20|=20one=20=20=20=20=20|=20=20=20=20= =20=20=20=2060=20|=20=20=20=20=20=20=2060=0A+=20[1,2)=20|=20= [2000-03-01,2000-04-01)=20|=20one^1=20=20=20|=20=20=20=20=20=20=20=2031=20= |=20=20=20=20=20=20=2031=0A+=20[1,2)=20|=20[2000-04-01,2000-06-01)=20|=20= one=20=20=20=20=20|=20=20=20=20=20=20=20=2061=20|=20=20=20=20=20=20=2061=0A= +=20[1,2)=20|=20[2000-07-01,2010-01-01)=20|=20one=20=20=20=20=20|=20=20=20= =20=20=203471=20|=20=20=20=20=203471=0A+=20[2,3)=20|=20= [2000-06-01,2000-07-01)=20|=20three^2=20|=20=20=20=20=20=20=20=2030=20|=20= =20=20=20=20=20=2030=0A+=20[3,4)=20|=20[2000-01-01,2000-03-01)=20|=20= three=20=20=20|=20=20=20=20=20=20=20=2060=20|=20=20=20=20=20=20=2060=0A+=20= [3,4)=20|=20[2000-03-01,2000-04-01)=20|=20three^1=20|=20=20=20=20=20=20=20= =2031=20|=20=20=20=20=20=20=2031=0A+=20[3,4)=20|=20= [2000-04-01,2000-06-01)=20|=20three=20=20=20|=20=20=20=20=20=20=20=2061=20= |=20=20=20=20=20=20=2061=0A+=20[3,4)=20|=20[2000-06-01,2000-07-01)=20|=20= five^2=20=20|=20=20=20=20=20=20=20=2030=20|=20=20=20=20=20=20=2030=0A+=20= [3,4)=20|=20[2000-07-01,2010-01-01)=20|=20three=20=20=20|=20=20=20=20=20=20= 3471=20|=20=20=20=20=203471=0A+=20[4,5)=20|=20[2000-06-01,2000-07-01)=20= |=20one^2=20=20=20|=20=20=20=20=20=20=20=2030=20|=20=20=20=20=20=20=2030=0A= +=20[5,6)=20|=20[2000-01-01,2000-03-01)=20|=20five=20=20=20=20|=20=20=20=20= =20=20=20=2060=20|=20=20=20=20=20=20=2060=0A+=20[5,6)=20|=20= [2000-03-01,2000-04-01)=20|=20five^1=20=20|=20=20=20=20=20=20=20=2031=20= |=20=20=20=20=20=20=2031=0A+=20[5,6)=20|=20[2000-04-01,2000-06-01)=20|=20= five=20=20=20=20|=20=20=20=20=20=20=20=2061=20|=20=20=20=20=20=20=2061=0A= +=20[5,6)=20|=20[2000-07-01,2010-01-01)=20|=20five=20=20=20=20|=20=20=20=20= =20=203471=20|=20=20=20=20=203471=0A=20(15=20rows)=0A=20=0A=20SELECT=20*=20= FROM=20temporal_partitioned_1=20ORDER=20BY=20id,=20valid_at;=0A-=20=20id=20= =20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20=20= name=20=20=20=0A--------+-------------------------+---------=0A-=20[1,2)=20= |=20[2000-01-01,2000-03-01)=20|=20one=0A-=20[1,2)=20|=20= [2000-03-01,2000-04-01)=20|=20one^1=0A-=20[1,2)=20|=20= [2000-04-01,2000-06-01)=20|=20one=0A-=20[1,2)=20|=20= [2000-07-01,2010-01-01)=20|=20one=0A-=20[2,3)=20|=20= [2000-06-01,2000-07-01)=20|=20three^2=0A+=20=20id=20=20=20|=20=20=20=20=20= =20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20=20name=20=20=20|=20= range_len=20=0A+-------+-------------------------+---------+-----------=0A= +=20[1,2)=20|=20[2000-01-01,2000-03-01)=20|=20one=20=20=20=20=20|=20=20=20= =20=20=20=20=2060=0A+=20[1,2)=20|=20[2000-03-01,2000-04-01)=20|=20one^1=20= =20=20|=20=20=20=20=20=20=20=2031=0A+=20[1,2)=20|=20= [2000-04-01,2000-06-01)=20|=20one=20=20=20=20=20|=20=20=20=20=20=20=20=20= 61=0A+=20[1,2)=20|=20[2000-07-01,2010-01-01)=20|=20one=20=20=20=20=20|=20= =20=20=20=20=203471=0A+=20[2,3)=20|=20[2000-06-01,2000-07-01)=20|=20= three^2=20|=20=20=20=20=20=20=20=2030=0A=20(5=20rows)=0A=20=0A=20SELECT=20= *=20FROM=20temporal_partitioned_3=20ORDER=20BY=20id,=20valid_at;=0A-=20=20= name=20=20=20|=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20= =20=20=20=20=20=20=0A----------+-------+-------------------------=0A-=20= three=20=20=20|=20[3,4)=20|=20[2000-01-01,2000-03-01)=0A-=20three^1=20|=20= [3,4)=20|=20[2000-03-01,2000-04-01)=0A-=20three=20=20=20|=20[3,4)=20|=20= [2000-04-01,2000-06-01)=0A-=20five^2=20=20|=20[3,4)=20|=20= [2000-06-01,2000-07-01)=0A-=20three=20=20=20|=20[3,4)=20|=20= [2000-07-01,2010-01-01)=0A-=20one^2=20=20=20|=20[4,5)=20|=20= [2000-06-01,2000-07-01)=0A+=20=20name=20=20=20|=20=20id=20=20=20|=20=20=20= =20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20range_len=20=0A= +---------+-------+-------------------------+-----------=0A+=20three=20=20= =20|=20[3,4)=20|=20[2000-01-01,2000-03-01)=20|=20=20=20=20=20=20=20=2060=0A= +=20three^1=20|=20[3,4)=20|=20[2000-03-01,2000-04-01)=20|=20=20=20=20=20=20= =20=2031=0A+=20three=20=20=20|=20[3,4)=20|=20[2000-04-01,2000-06-01)=20|=20= =20=20=20=20=20=20=2061=0A+=20five^2=20=20|=20[3,4)=20|=20= [2000-06-01,2000-07-01)=20|=20=20=20=20=20=20=20=2030=0A+=20three=20=20=20= |=20[3,4)=20|=20[2000-07-01,2010-01-01)=20|=20=20=20=20=20=203471=0A+=20= one^2=20=20=20|=20[4,5)=20|=20[2000-06-01,2000-07-01)=20|=20=20=20=20=20=20= =20=2030=0A=20(6=20rows)=0A=20=0A=20SELECT=20*=20FROM=20= temporal_partitioned_5=20ORDER=20BY=20id,=20valid_at;=0A-=20=20name=20=20= |=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20=20id=20=20= =20=0A---------+-------------------------+-------=0A-=20five=20=20=20|=20= [2000-01-01,2000-03-01)=20|=20[5,6)=0A-=20five^1=20|=20= [2000-03-01,2000-04-01)=20|=20[5,6)=0A-=20five=20=20=20|=20= [2000-04-01,2000-06-01)=20|=20[5,6)=0A-=20five=20=20=20|=20= [2000-07-01,2010-01-01)=20|=20[5,6)=0A+=20=20name=20=20|=20=20=20=20=20=20= =20=20valid_at=20=20=20=20=20=20=20=20=20|=20=20id=20=20=20|=20range_len=20= =0A+--------+-------------------------+-------+-----------=0A+=20five=20=20= =20|=20[2000-01-01,2000-03-01)=20|=20[5,6)=20|=20=20=20=20=20=20=20=2060=0A= +=20five^1=20|=20[2000-03-01,2000-04-01)=20|=20[5,6)=20|=20=20=20=20=20=20= =20=2031=0A+=20five=20=20=20|=20[2000-04-01,2000-06-01)=20|=20[5,6)=20|=20= =20=20=20=20=20=20=2061=0A+=20five=20=20=20|=20[2000-07-01,2010-01-01)=20= |=20[5,6)=20|=20=20=20=20=20=203471=0A=20(4=20rows)=0A=20=0A=20DROP=20= TABLE=20temporal_partitioned;=0A@@=20-2152,4=20+2170,115=20@@=20SELECT=20= *=20FROM=20fpo_rule=20ORDER=20BY=20f1;=0A=20(2=20rows)=0A=20=0A=20DROP=20= TABLE=20fpo_rule;=0A+--=20UPDATE=20FOR=20PORTION=20OF=20with=20generated=20= stored=20columns=0A+--=20The=20generated=20column=20depends=20on=20the=20= range=20column,=20so=20it=20must=20be=0A+--=20recomputed=20when=20FOR=20= PORTION=20OF=20narrows=20the=20range.=0A+CREATE=20TABLE=20fpo_generated=20= (=0A+=20=20id=20int,=0A+=20=20valid_at=20int4range,=0A+=20=20range_len=20= int=20GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20lower(valid_at))=20= STORED,=0A+=20=20range_lenv=20int=20GENERATED=20ALWAYS=20AS=20= (upper(valid_at)=20-=20lower(valid_at))=0A+);=0A+INSERT=20INTO=20= fpo_generated=20(id,=20valid_at)=20VALUES=20(1,=20'[10,100)');=0A+SELECT=20= *=20FROM=20fpo_generated=20ORDER=20BY=20valid_at;=0A+=20id=20|=20= valid_at=20|=20range_len=20|=20range_lenv=20=0A= +----+----------+-----------+------------=0A+=20=201=20|=20[10,100)=20|=20= =20=20=20=20=20=20=2090=20|=20=20=20=20=20=20=20=20=2090=0A+(1=20row)=0A= +=0A+CREATE=20TRIGGER=20fpo_before_row1=0A+=20=20BEFORE=20UPDATE=20OF=20= valid_at=20ON=20fpo_generated=0A+=20=20FOR=20EACH=20ROW=20EXECUTE=20= PROCEDURE=20dump_trigger(false,=20false);=0A+CREATE=20TRIGGER=20= fpo_before_row2=0A+=20=20BEFORE=20UPDATE=20OF=20valid_at=20ON=20= fpo_generated=0A+=20=20FOR=20EACH=20STATEMENT=20EXECUTE=20PROCEDURE=20= dump_trigger(false,=20false);=0A+--=20After=20the=20FOR=20PORTION=20OF=20= (FPO)=20update,=20all=20three=20resulting=20rows=0A+--=20= (leftover-before,=20updated,=20and=20leftover-after)=20must=20contain=20= the=20correct=0A+--=20values=20for=20range_len=20and=20range_lenv.=0A+--=20= Triggers=20fpo_before_row1=20and=20fpo_before_row2=20should=20also=20be=20= fired.=0A+UPDATE=20fpo_generated=0A+=20=20FOR=20PORTION=20OF=20valid_at=20= FROM=2030=20TO=2070=0A+=20=20SET=20id=20=3D=202;=0A+NOTICE:=20=20= fpo_before_row2:=20BEFORE=20UPDATE=20STATEMENT:=0A+NOTICE:=20=20=20=20= old:=20=0A+NOTICE:=20=20=20=20new:=20=0A+NOTICE:=20=20= fpo_before_row1:=20BEFORE=20UPDATE=20ROW:=0A+NOTICE:=20=20=20=20old:=20= [10,100)=0A+NOTICE:=20=20=20=20new:=20[30,70)=0A+SELECT=20*=20FROM=20= fpo_generated=20ORDER=20BY=20valid_at;=0A+=20id=20|=20valid_at=20|=20= range_len=20|=20range_lenv=20=0A= +----+----------+-----------+------------=0A+=20=201=20|=20[10,30)=20=20= |=20=20=20=20=20=20=20=2020=20|=20=20=20=20=20=20=20=20=2020=0A+=20=202=20= |=20[30,70)=20=20|=20=20=20=20=20=20=20=2040=20|=20=20=20=20=20=20=20=20=20= 40=0A+=20=201=20|=20[70,100)=20|=20=20=20=20=20=20=20=2030=20|=20=20=20=20= =20=20=20=20=2030=0A+(3=20rows)=0A+=0A+--=20Also=20test=20with=20a=20= generated=20column=20that=20references=20both=20a=20SET=20column=0A+--=20= and=20the=20range=20column.=0A+DROP=20TABLE=20fpo_generated;=0A+CREATE=20= TABLE=20fpo_generated=20(=0A+=20=20id=20int,=0A+=20=20valid_at=20= int4range,=0A+=20=20id_plus_len=20int=20GENERATED=20ALWAYS=20AS=20(id=20= +=20upper(valid_at)=20-=20lower(valid_at))=20STORED,=0A+=20=20= id_plus_lenv=20int=20GENERATED=20ALWAYS=20AS=20(id=20+=20upper(valid_at)=20= -=20lower(valid_at))=0A+);=0A+INSERT=20INTO=20fpo_generated=20(id,=20= valid_at)=20VALUES=20(1,=20'[10,100)');=0A+SELECT=20*=20FROM=20= fpo_generated=20ORDER=20BY=20valid_at;=0A+=20id=20|=20valid_at=20|=20= id_plus_len=20|=20id_plus_lenv=20=0A= +----+----------+-------------+--------------=0A+=20=201=20|=20[10,100)=20= |=20=20=20=20=20=20=20=20=20=2091=20|=20=20=20=20=20=20=20=20=20=20=2091=0A= +(1=20row)=0A+=0A+UPDATE=20fpo_generated=0A+=20=20FOR=20PORTION=20OF=20= valid_at=20FROM=2030=20TO=2070=0A+=20=20SET=20id=20=3D=202;=0A+SELECT=20= *=20FROM=20fpo_generated=20ORDER=20BY=20valid_at;=0A+=20id=20|=20= valid_at=20|=20id_plus_len=20|=20id_plus_lenv=20=0A= +----+----------+-------------+--------------=0A+=20=201=20|=20[10,30)=20= =20|=20=20=20=20=20=20=20=20=20=2021=20|=20=20=20=20=20=20=20=20=20=20=20= 21=0A+=20=202=20|=20[30,70)=20=20|=20=20=20=20=20=20=20=20=20=2042=20|=20= =20=20=20=20=20=20=20=20=20=2042=0A+=20=201=20|=20[70,100)=20|=20=20=20=20= =20=20=20=20=20=2031=20|=20=20=20=20=20=20=20=20=20=20=2031=0A+(3=20= rows)=0A+=0A+DROP=20TABLE=20fpo_generated;=0A+--=20UPDATE=20FOR=20= PORTION=20OF=20with=20table=20inheritance=0A+--=20Leftover=20rows=20must=20= stay=20in=20the=20child=20table,=20preserving=20child-specific=20= columns.=0A+CREATE=20TABLE=20fpo_inh_parent=20(=0A+=20=20id=20int4range,=0A= +=20=20valid_at=20daterange,=0A+=20=20name=20text=0A+);=0A+CREATE=20= TABLE=20fpo_inh_child=20(=0A+=20=20description=20text=0A+)=20INHERITS=20= (fpo_inh_parent);=0A+INSERT=20INTO=20fpo_inh_child=20(id,=20valid_at,=20= name,=20description)=20VALUES=0A+=20=20('[1,2)',=20= '[2018-01-01,2019-01-01)',=20'one',=20'initial');=0A+--=20Update=20= targets=20the=20parent;=20the=20matching=20row=20lives=20in=20the=20= child.=0A+UPDATE=20fpo_inh_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20= '2018-04-01'=20TO=20'2018-10-01'=0A+=20=20SET=20name=20=3D=20'one^1';=0A= +--=20All=20three=20rows=20should=20be=20in=20the=20child,=20with=20= description=20preserved.=0A+SELECT=20tableoid::regclass,=20*=20FROM=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=20=20=20tableoid=20=20=20=20= |=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20= =20|=20name=20=20=0A= +---------------+-------+-------------------------+-------=0A+=20= fpo_inh_child=20|=20[1,2)=20|=20[2018-01-01,2018-04-01)=20|=20one=0A+=20= fpo_inh_child=20|=20[1,2)=20|=20[2018-04-01,2018-10-01)=20|=20one^1=0A+=20= fpo_inh_child=20|=20[1,2)=20|=20[2018-10-01,2019-01-01)=20|=20one=0A+(3=20= rows)=0A+=0A+SELECT=20*=20FROM=20fpo_inh_child=20ORDER=20BY=20valid_at;=0A= +=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20= =20|=20name=20=20|=20description=20=0A= +-------+-------------------------+-------+-------------=0A+=20[1,2)=20|=20= [2018-01-01,2018-04-01)=20|=20one=20=20=20|=20initial=0A+=20[1,2)=20|=20= [2018-04-01,2018-10-01)=20|=20one^1=20|=20initial=0A+=20[1,2)=20|=20= [2018-10-01,2019-01-01)=20|=20one=20=20=20|=20initial=0A+(3=20rows)=0A+=0A= +--=20No=20rows=20should=20have=20leaked=20into=20the=20parent.=0A= +SELECT=20*=20FROM=20ONLY=20fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=20= id=20|=20valid_at=20|=20name=20=0A+----+----------+------=0A+(0=20rows)=0A= +=0A+DROP=20TABLE=20fpo_inh_parent=20CASCADE;=0A+NOTICE:=20=20drop=20= cascades=20to=20table=20fpo_inh_child=0A=20RESET=20datestyle;=0Adiff=20= --git=20a/src/test/regress/sql/for_portion_of.sql=20= b/src/test/regress/sql/for_portion_of.sql=0Aindex=20= fd79a9b78e7..04e0dba6375=20100644=0A---=20= a/src/test/regress/sql/for_portion_of.sql=0A+++=20= b/src/test/regress/sql/for_portion_of.sql=0A@@=20-913,6=20+913,10=20@@=20= CREATE=20TRIGGER=20fpo_before_stmt=0A=20=20=20BEFORE=20INSERT=20OR=20= UPDATE=20OR=20DELETE=20ON=20for_portion_of_test=0A=20=20=20FOR=20EACH=20= STATEMENT=20EXECUTE=20PROCEDURE=20dump_trigger(false,=20false);=0A=20=0A= +CREATE=20TRIGGER=20fpo_before_stmt1=0A+=20=20BEFORE=20UPDATE=20OF=20= valid_at=20ON=20for_portion_of_test=0A+=20=20FOR=20EACH=20STATEMENT=20= EXECUTE=20PROCEDURE=20dump_trigger(false,=20false);=0A+=0A=20CREATE=20= TRIGGER=20fpo_after_insert_stmt=0A=20=20=20AFTER=20INSERT=20ON=20= for_portion_of_test=0A=20=20=20FOR=20EACH=20STATEMENT=20EXECUTE=20= PROCEDURE=20dump_trigger(false,=20false);=0A@@=20-931,6=20+935,10=20@@=20= CREATE=20TRIGGER=20fpo_before_row=0A=20=20=20BEFORE=20INSERT=20OR=20= UPDATE=20OR=20DELETE=20ON=20for_portion_of_test=0A=20=20=20FOR=20EACH=20= ROW=20EXECUTE=20PROCEDURE=20dump_trigger(false,=20false);=0A=20=0A= +CREATE=20TRIGGER=20fpo_before_row1=0A+=20=20BEFORE=20UPDATE=20OF=20= valid_at=20ON=20for_portion_of_test=0A+=20=20FOR=20EACH=20ROW=20EXECUTE=20= PROCEDURE=20dump_trigger(false,=20false);=0A+=0A=20CREATE=20TRIGGER=20= fpo_after_insert_row=0A=20=20=20AFTER=20INSERT=20ON=20= for_portion_of_test=0A=20=20=20FOR=20EACH=20ROW=20EXECUTE=20PROCEDURE=20= dump_trigger(false,=20false);=0A@@=20-1292,6=20+1300,7=20@@=20DROP=20= TABLE=20for_portion_of_test2;=0A=20DROP=20TYPE=20mydaterange;=0A=20=0A=20= --=20Test=20FOR=20PORTION=20OF=20against=20a=20partitioned=20table.=0A= +--=20Include=20a=20GENERATED=20STORED=20column=20to=20test=20= updatedCols=20column=20mapping.=0A=20--=20temporal_partitioned_1=20has=20= the=20same=20attnums=20as=20the=20root=0A=20--=20temporal_partitioned_3=20= has=20the=20different=20attnums=20from=20the=20root=0A=20--=20= temporal_partitioned_5=20has=20the=20different=20attnums=20too,=20but=20= reversed=0A@@=20-1300,6=20+1309,7=20@@=20CREATE=20TABLE=20= temporal_partitioned=20(=0A=20=20=20id=20int4range,=0A=20=20=20valid_at=20= daterange,=0A=20=20=20name=20text,=0A+=20=20range_len=20int=20GENERATED=20= ALWAYS=20AS=20(upper(valid_at)=20-=20lower(valid_at))=20STORED,=0A=20=20=20= CONSTRAINT=20temporal_paritioned_uq=20UNIQUE=20(id,=20valid_at=20WITHOUT=20= OVERLAPS)=0A=20)=20PARTITION=20BY=20LIST=20(id);=0A=20CREATE=20TABLE=20= temporal_partitioned_1=20PARTITION=20OF=20temporal_partitioned=20FOR=20= VALUES=20IN=20('[1,2)',=20'[2,3)');=0A@@=20-1307,13=20+1317,15=20@@=20= CREATE=20TABLE=20temporal_partitioned_3=20PARTITION=20OF=20= temporal_partitioned=20FOR=20VALUES=0A=20CREATE=20TABLE=20= temporal_partitioned_5=20PARTITION=20OF=20temporal_partitioned=20FOR=20= VALUES=20IN=20('[5,6)',=20'[6,7)');=0A=20=0A=20ALTER=20TABLE=20= temporal_partitioned=20DETACH=20PARTITION=20temporal_partitioned_3;=0A= -ALTER=20TABLE=20temporal_partitioned_3=20DROP=20COLUMN=20id,=20DROP=20= COLUMN=20valid_at;=0A+ALTER=20TABLE=20temporal_partitioned_3=20DROP=20= COLUMN=20id,=20DROP=20COLUMN=20valid_at=20CASCADE;=0A=20ALTER=20TABLE=20= temporal_partitioned_3=20ADD=20COLUMN=20id=20int4range=20NOT=20NULL,=20= ADD=20COLUMN=20valid_at=20daterange=20NOT=20NULL;=0A+ALTER=20TABLE=20= temporal_partitioned_3=20ADD=20COLUMN=20range_len=20int=20GENERATED=20= ALWAYS=20AS=20(upper(valid_at)=20-=20lower(valid_at))=20STORED;=0A=20= ALTER=20TABLE=20temporal_partitioned=20ATTACH=20PARTITION=20= temporal_partitioned_3=20FOR=20VALUES=20IN=20('[3,4)',=20'[4,5)');=0A=20=0A= =20ALTER=20TABLE=20temporal_partitioned=20DETACH=20PARTITION=20= temporal_partitioned_5;=0A-ALTER=20TABLE=20temporal_partitioned_5=20DROP=20= COLUMN=20id,=20DROP=20COLUMN=20valid_at;=0A+ALTER=20TABLE=20= temporal_partitioned_5=20DROP=20COLUMN=20id,=20DROP=20COLUMN=20valid_at=20= CASCADE;=0A=20ALTER=20TABLE=20temporal_partitioned_5=20ADD=20COLUMN=20= valid_at=20daterange=20NOT=20NULL,=20ADD=20COLUMN=20id=20int4range=20NOT=20= NULL;=0A+ALTER=20TABLE=20temporal_partitioned_5=20ADD=20COLUMN=20= range_len=20int=20GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20= lower(valid_at))=20STORED;=0A=20ALTER=20TABLE=20temporal_partitioned=20= ATTACH=20PARTITION=20temporal_partitioned_5=20FOR=20VALUES=20IN=20= ('[5,6)',=20'[6,7)');=0A=20=0A=20INSERT=20INTO=20temporal_partitioned=20= (id,=20valid_at,=20name)=20VALUES=0A@@=20-1358,7=20+1370,7=20@@=20UPDATE=20= temporal_partitioned=20FOR=20PORTION=20OF=20valid_at=20FROM=20= '2000-06-01'=20TO=20'2000-0=0A=20=0A=20--=20Update=20all=20partitions=20= at=20once=20(each=20with=20leftovers)=0A=20=0A-SELECT=20*=20FROM=20= temporal_partitioned=20ORDER=20BY=20id,=20valid_at;=0A+SELECT=20*,=20= upper(valid_at)=20-=20lower(valid_at)=20FROM=20temporal_partitioned=20= ORDER=20BY=20id,=20valid_at;=0A=20SELECT=20*=20FROM=20= temporal_partitioned_1=20ORDER=20BY=20id,=20valid_at;=0A=20SELECT=20*=20= FROM=20temporal_partitioned_3=20ORDER=20BY=20id,=20valid_at;=0A=20SELECT=20= *=20FROM=20temporal_partitioned_5=20ORDER=20BY=20id,=20valid_at;=0A@@=20= -1398,4=20+1410,80=20@@=20SELECT=20*=20FROM=20fpo_rule=20ORDER=20BY=20= f1;=0A=20=0A=20DROP=20TABLE=20fpo_rule;=0A=20=0A+--=20UPDATE=20FOR=20= PORTION=20OF=20with=20generated=20stored=20columns=0A+--=20The=20= generated=20column=20depends=20on=20the=20range=20column,=20so=20it=20= must=20be=0A+--=20recomputed=20when=20FOR=20PORTION=20OF=20narrows=20the=20= range.=0A+CREATE=20TABLE=20fpo_generated=20(=0A+=20=20id=20int,=0A+=20=20= valid_at=20int4range,=0A+=20=20range_len=20int=20GENERATED=20ALWAYS=20AS=20= (upper(valid_at)=20-=20lower(valid_at))=20STORED,=0A+=20=20range_lenv=20= int=20GENERATED=20ALWAYS=20AS=20(upper(valid_at)=20-=20lower(valid_at))=0A= +);=0A+INSERT=20INTO=20fpo_generated=20(id,=20valid_at)=20VALUES=20(1,=20= '[10,100)');=0A+=0A+SELECT=20*=20FROM=20fpo_generated=20ORDER=20BY=20= valid_at;=0A+=0A+CREATE=20TRIGGER=20fpo_before_row1=0A+=20=20BEFORE=20= UPDATE=20OF=20valid_at=20ON=20fpo_generated=0A+=20=20FOR=20EACH=20ROW=20= EXECUTE=20PROCEDURE=20dump_trigger(false,=20false);=0A+=0A+CREATE=20= TRIGGER=20fpo_before_row2=0A+=20=20BEFORE=20UPDATE=20OF=20valid_at=20ON=20= fpo_generated=0A+=20=20FOR=20EACH=20STATEMENT=20EXECUTE=20PROCEDURE=20= dump_trigger(false,=20false);=0A+=0A+--=20After=20the=20FOR=20PORTION=20= OF=20(FPO)=20update,=20all=20three=20resulting=20rows=0A+--=20= (leftover-before,=20updated,=20and=20leftover-after)=20must=20contain=20= the=20correct=0A+--=20values=20for=20range_len=20and=20range_lenv.=0A+--=20= Triggers=20fpo_before_row1=20and=20fpo_before_row2=20should=20also=20be=20= fired.=0A+UPDATE=20fpo_generated=0A+=20=20FOR=20PORTION=20OF=20valid_at=20= FROM=2030=20TO=2070=0A+=20=20SET=20id=20=3D=202;=0A+=0A+SELECT=20*=20= FROM=20fpo_generated=20ORDER=20BY=20valid_at;=0A+=0A+--=20Also=20test=20= with=20a=20generated=20column=20that=20references=20both=20a=20SET=20= column=0A+--=20and=20the=20range=20column.=0A+DROP=20TABLE=20= fpo_generated;=0A+CREATE=20TABLE=20fpo_generated=20(=0A+=20=20id=20int,=0A= +=20=20valid_at=20int4range,=0A+=20=20id_plus_len=20int=20GENERATED=20= ALWAYS=20AS=20(id=20+=20upper(valid_at)=20-=20lower(valid_at))=20STORED,=0A= +=20=20id_plus_lenv=20int=20GENERATED=20ALWAYS=20AS=20(id=20+=20= upper(valid_at)=20-=20lower(valid_at))=0A+);=0A+=0A+INSERT=20INTO=20= fpo_generated=20(id,=20valid_at)=20VALUES=20(1,=20'[10,100)');=0A+SELECT=20= *=20FROM=20fpo_generated=20ORDER=20BY=20valid_at;=0A+=0A+UPDATE=20= fpo_generated=0A+=20=20FOR=20PORTION=20OF=20valid_at=20FROM=2030=20TO=20= 70=0A+=20=20SET=20id=20=3D=202;=0A+SELECT=20*=20FROM=20fpo_generated=20= ORDER=20BY=20valid_at;=0A+DROP=20TABLE=20fpo_generated;=0A+=0A+=0A+--=20= UPDATE=20FOR=20PORTION=20OF=20with=20table=20inheritance=0A+--=20= Leftover=20rows=20must=20stay=20in=20the=20child=20table,=20preserving=20= child-specific=20columns.=0A+CREATE=20TABLE=20fpo_inh_parent=20(=0A+=20=20= id=20int4range,=0A+=20=20valid_at=20daterange,=0A+=20=20name=20text=0A= +);=0A+CREATE=20TABLE=20fpo_inh_child=20(=0A+=20=20description=20text=0A= +)=20INHERITS=20(fpo_inh_parent);=0A+INSERT=20INTO=20fpo_inh_child=20= (id,=20valid_at,=20name,=20description)=20VALUES=0A+=20=20('[1,2)',=20= '[2018-01-01,2019-01-01)',=20'one',=20'initial');=0A+=0A+--=20Update=20= targets=20the=20parent;=20the=20matching=20row=20lives=20in=20the=20= child.=0A+UPDATE=20fpo_inh_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20= '2018-04-01'=20TO=20'2018-10-01'=0A+=20=20SET=20name=20=3D=20'one^1';=0A= +=0A+--=20All=20three=20rows=20should=20be=20in=20the=20child,=20with=20= description=20preserved.=0A+SELECT=20tableoid::regclass,=20*=20FROM=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+SELECT=20*=20FROM=20= fpo_inh_child=20ORDER=20BY=20valid_at;=0A+--=20No=20rows=20should=20have=20= leaked=20into=20the=20parent.=0A+SELECT=20*=20FROM=20ONLY=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=0A+DROP=20TABLE=20= fpo_inh_parent=20CASCADE;=0A+=0A=20RESET=20datestyle;=0A--=20=0A2.50.1=20= (Apple=20Git-155)=0A=0A= --Apple-Mail=_69E186E3-7BA3-4F0D-AF51-377E8FE410AB Content-Disposition: attachment; filename=v10-0002-Fix-FOR-PORTION-OF-on-inherited-children-with-di.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="v10-0002-Fix-FOR-PORTION-OF-on-inherited-children-with-di.patch" Content-Transfer-Encoding: quoted-printable =46rom=20e639fc0d40572b5c72afe817dbe66e37852a66b5=20Mon=20Sep=2017=20= 00:00:00=202001=0AFrom:=20"Chao=20Li=20(Evan)"=20=0A= Date:=20Thu,=207=20May=202026=2013:32:05=20+0800=0ASubject:=20[PATCH=20= v10=202/2]=20Fix=20FOR=20PORTION=20OF=20on=20inherited=20children=20with=0A= =20differing=20attnos=0A=0A---=0A=20= src/backend/executor/nodeModifyTable.c=20=20=20=20=20=20=20|=2036=20= ++++----=0A=20src/test/regress/expected/for_portion_of.out=20|=2088=20= ++++++++++++++++++++=0A=20src/test/regress/sql/for_portion_of.sql=20=20=20= =20=20=20|=2048=20+++++++++++=0A=203=20files=20changed,=20157=20= insertions(+),=2015=20deletions(-)=0A=0Adiff=20--git=20= a/src/backend/executor/nodeModifyTable.c=20= b/src/backend/executor/nodeModifyTable.c=0Aindex=20= 81f5afc9fb7..f6bf4ebbb11=20100644=0A---=20= a/src/backend/executor/nodeModifyTable.c=0A+++=20= b/src/backend/executor/nodeModifyTable.c=0A@@=20-1493,9=20+1493,9=20@@=20= ExecForPortionOfLeftovers(ModifyTableContext=20*context,=0A=20=09= fcinfo->args[1].isnull=20=3D=20false;=0A=20=0A=20=09/*=0A-=09=20*=20For=20= partitioned=20tables,=20we=20must=20read=20leftovers=20with=20the=20= tuple=20descriptor=0A-=09=20*=20of=20the=20child=20table,=20but=20insert=20= into=20the=20root=20table=20to=20enable=20tuple=0A-=09=20*=20routing.=20=20= So=20leftoverSlot=20is=20configured=20with=20the=20root's=20tuple=0A+=09=20= *=20For=20partitioned=20tables,=20we=20must=20read=20leftovers=20with=20= the=20tuple=0A+=09=20*=20descriptor=20of=20the=20child=20table,=20but=20= insert=20into=20the=20root=20table=20to=20enable=0A+=09=20*=20tuple=20= routing.=20=20So=20leftoverSlot=20is=20configured=20with=20the=20root's=20= tuple=0A=20=09=20*=20descriptor.=20=20However,=20for=20traditional=20= table=20inheritance,=20we=20don't=20need=0A=20=09=20*=20tuple=20routing=20= and=20just=20insert=20directly=20into=20the=20child=20table=20to=20= preserve=0A=20=09=20*=20child-specific=20columns.=20=20In=20that=20case,=20= leftoverSlot=20uses=20the=20child's=0A@@=20-5861,6=20+5861,7=20@@=20= ExecInitForPortionOf(ModifyTableState=20*mtstate,=20EState=20*estate,=20= ResultRelInfo=20*r=0A=20=09ForPortionOfState=20*leafState;=0A=20=09= ResultRelInfo=20*rootRelInfo=20=3D=20mtstate->rootResultRelInfo;=0A=20=09= ForPortionOfState=20*fpoState;=0A+=09TupleConversionMap=20*map;=0A=20=0A=20= =09if=20(!rootRelInfo)=0A=20=09=09elog(ERROR,=20"no=20root=20relation=20= but=20ri_forPortionOf=20is=20uninitialized");=0A@@=20-5875,34=20+5876,39=20= @@=20ExecInitForPortionOf(ModifyTableState=20*mtstate,=20EState=20= *estate,=20ResultRelInfo=20*r=0A=20=09leafState->fp_rangeName=20=3D=20= fpoState->fp_rangeName;=0A=20=09leafState->fp_rangeType=20=3D=20= fpoState->fp_rangeType;=0A=20=09leafState->fp_targetRange=20=3D=20= fpoState->fp_targetRange;=0A+=09map=20=3D=20= ExecGetChildToRootMap(resultRelInfo);=0A+=0A+=09/*=0A+=09=20*=20= fp_rangeAttno=20must=20match=20the=20tuple=20layout=20used=20for=20= reading=20the=20old=0A+=09=20*=20range=20value.=20=20The=20query=20uses=20= the=20target=20relation's=20attno,=20so=20translate=0A+=09=20*=20it=20to=20= the=20child=20attno=20when=20the=20child=20has=20a=20different=20column=20= layout.=0A+=09=20*/=0A+=09if=20(map)=0A+=09=09leafState->fp_rangeAttno=20= =3D=20map->attrMap->attnums[fpoState->fp_rangeAttno=20-=201];=0A+=09else=0A= +=09=09leafState->fp_rangeAttno=20=3D=20fpoState->fp_rangeAttno;=0A=20=0A= =20=09/*=0A-=09=20*=20For=20partitioned=20tables=20we=20must=20read=20= the=20leftovers=20using=20the=20child=20table's=0A-=09=20*=20tuple=20= descriptor,=20but=20then=20insert=20them=20into=20the=20root=20table=20= (using=20its=0A-=09=20*=20tuple=20descriptor)=20so=20we=20get=20tuple=20= routing.=0A+=09=20*=20For=20partitioned=20tables=20we=20must=20read=20= the=20leftovers=20using=20the=20child=0A+=09=20*=20table's=20tuple=20= descriptor,=20but=20then=20insert=20them=20into=20the=20root=20table=0A+=09= =20*=20(using=20its=20tuple=20descriptor)=20so=20we=20get=20tuple=20= routing.=0A=20=09=20*=0A-=09=20*=20For=20traditional=20table=20= inheritance,=20we=20read=20and=20insert=20directly=20into=20this=0A-=09=20= *=20resultRelInfo;=20no=20tuple=20routing=20to=20the=20parent=20is=20= required.=0A+=09=20*=20For=20traditional=20table=20inheritance,=20we=20= read=20and=20insert=20directly=20into=0A+=09=20*=20this=20resultRelInfo;=20= no=20tuple=20routing=20to=20the=20parent=20is=20required.=0A=20=09=20*/=0A= =20=09if=20(rootRelInfo->ri_RelationDesc->rd_rel->relkind=20=3D=3D=20= RELKIND_PARTITIONED_TABLE)=0A=20=09{=0A-=09=09TupleConversionMap=20*map=20= =3D=20ExecGetChildToRootMap(resultRelInfo);=0A-=09=09if=20(map)=0A-=09=09= =09leafState->fp_rangeAttno=20=3D=20= map->attrMap->attnums[fpoState->fp_rangeAttno=20-=201];=0A-=09=09else=0A= -=09=09=09leafState->fp_rangeAttno=20=3D=20fpoState->fp_rangeAttno;=0A=20= =09=09leafState->fp_Leftover=20=3D=20fpoState->fp_Leftover;=0A=20=09}=0A=20= =09else=0A=20=09{=0A-=09=09leafState->fp_rangeAttno=20=3D=20= fpoState->fp_rangeAttno;=0A=20=09=09leafState->fp_Leftover=20=3D=0A=20=09= =09=09ExecInitExtraTupleSlot(mtstate->ps.state,=0A=20=09=09=09=09=09=09=09= =09=20=20=20RelationGetDescr(resultRelInfo->ri_RelationDesc),=0A=20=09=09= =09=09=09=09=09=09=20=20=20&TTSOpsVirtual);=0A=20=09}=0A=20=0A-=09/*=20= Each=20partition=20needs=20a=20slot=20matching=20its=20tuple=20= descriptor=20*/=0A+=09/*=20Each=20child=20relation=20needs=20a=20slot=20= matching=20its=20tuple=20descriptor=20*/=0A=20=09leafState->fp_Existing=20= =3D=0A=20=09=09table_slot_create(resultRelInfo->ri_RelationDesc,=0A=20=09= =09=09=09=09=09=20=20&mtstate->ps.state->es_tupleTable);=0Adiff=20--git=20= a/src/test/regress/expected/for_portion_of.out=20= b/src/test/regress/expected/for_portion_of.out=0Aindex=20= 91241463991..8c0a35f85e5=20100644=0A---=20= a/src/test/regress/expected/for_portion_of.out=0A+++=20= b/src/test/regress/expected/for_portion_of.out=0A@@=20-2279,6=20+2279,94=20= @@=20SELECT=20*=20FROM=20ONLY=20fpo_inh_parent=20ORDER=20BY=20valid_at;=0A= =20----+----------+------=0A=20(0=20rows)=0A=20=0A+TRUNCATE=20= fpo_inh_child,=20fpo_inh_parent;=0A+INSERT=20INTO=20fpo_inh_child=20(id,=20= valid_at,=20name,=20description)=20VALUES=0A+=20=20('[1,2)',=20= '[2018-01-01,2019-01-01)',=20'one',=20'initial');=0A+DELETE=20FROM=20= fpo_inh_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20'2018-04-01'=20= TO=20'2018-10-01';=0A+SELECT=20tableoid::regclass,=20*=20FROM=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=20=20=20tableoid=20=20=20=20= |=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20= =20|=20name=20=0A= +---------------+-------+-------------------------+------=0A+=20= fpo_inh_child=20|=20[1,2)=20|=20[2018-01-01,2018-04-01)=20|=20one=0A+=20= fpo_inh_child=20|=20[1,2)=20|=20[2018-10-01,2019-01-01)=20|=20one=0A+(2=20= rows)=0A+=0A+SELECT=20*=20FROM=20fpo_inh_child=20ORDER=20BY=20valid_at;=0A= +=20=20id=20=20=20|=20=20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20= =20|=20name=20|=20description=20=0A= +-------+-------------------------+------+-------------=0A+=20[1,2)=20|=20= [2018-01-01,2018-04-01)=20|=20one=20=20|=20initial=0A+=20[1,2)=20|=20= [2018-10-01,2019-01-01)=20|=20one=20=20|=20initial=0A+(2=20rows)=0A+=0A= +SELECT=20*=20FROM=20ONLY=20fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=20= id=20|=20valid_at=20|=20name=20=0A+----+----------+------=0A+(0=20rows)=0A= +=0A=20DROP=20TABLE=20fpo_inh_parent=20CASCADE;=0A=20NOTICE:=20=20drop=20= cascades=20to=20table=20fpo_inh_child=0A+--=20UPDATE=20FOR=20PORTION=20= OF=20with=20multiple=20inheritance=0A+--=20Leftover=20rows=20must=20stay=20= in=20the=20child=20table,=20even=20if=20the=20range=20column's=0A+--=20= attnum=20differs=20between=20the=20target=20parent=20and=20child.=0A= +CREATE=20TABLE=20temporal_parent=20(=0A+=20=20id=20int,=0A+=20=20= valid_at=20daterange,=0A+=20=20name=20text=0A+);=0A+CREATE=20TABLE=20= other_parent=20(=0A+=20=20prefix=20text,=0A+=20=20note=20text=0A+);=0A= +CREATE=20TABLE=20mi_child=20()=20INHERITS=20(other_parent,=20= temporal_parent);=0A+INSERT=20INTO=20mi_child=20(prefix,=20note,=20id,=20= valid_at,=20name)=20VALUES=0A+=20=20('pfx',=20'memo',=201,=20= daterange('2000-01-01',=20'2010-01-01'),=20'old');=0A+UPDATE=20= temporal_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20'2001-01-01'=20= TO=20'2002-01-01'=0A+=20=20SET=20name=20=3D=20'new'=0A+=20=20WHERE=20id=20= =3D=201;=0A+SELECT=20tableoid::regclass,=20*=20FROM=20temporal_parent=20= ORDER=20BY=20valid_at;=0A+=20tableoid=20|=20id=20|=20=20=20=20=20=20=20=20= valid_at=20=20=20=20=20=20=20=20=20|=20name=20=0A= +----------+----+-------------------------+------=0A+=20mi_child=20|=20=20= 1=20|=20[2000-01-01,2001-01-01)=20|=20old=0A+=20mi_child=20|=20=201=20|=20= [2001-01-01,2002-01-01)=20|=20new=0A+=20mi_child=20|=20=201=20|=20= [2002-01-01,2010-01-01)=20|=20old=0A+(3=20rows)=0A+=0A+SELECT=20*=20FROM=20= mi_child=20ORDER=20BY=20valid_at;=0A+=20prefix=20|=20note=20|=20id=20|=20= =20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20name=20=0A= +--------+------+----+-------------------------+------=0A+=20pfx=20=20=20= =20|=20memo=20|=20=201=20|=20[2000-01-01,2001-01-01)=20|=20old=0A+=20pfx=20= =20=20=20|=20memo=20|=20=201=20|=20[2001-01-01,2002-01-01)=20|=20new=0A+=20= pfx=20=20=20=20|=20memo=20|=20=201=20|=20[2002-01-01,2010-01-01)=20|=20= old=0A+(3=20rows)=0A+=0A+SELECT=20*=20FROM=20ONLY=20temporal_parent=20= ORDER=20BY=20valid_at;=0A+=20id=20|=20valid_at=20|=20name=20=0A= +----+----------+------=0A+(0=20rows)=0A+=0A+TRUNCATE=20mi_child,=20= other_parent,=20temporal_parent;=0A+INSERT=20INTO=20mi_child=20(prefix,=20= note,=20id,=20valid_at,=20name)=20VALUES=0A+=20=20('pfx',=20'memo',=201,=20= daterange('2000-01-01',=20'2010-01-01'),=20'old');=0A+DELETE=20FROM=20= temporal_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20'2001-01-01'=20= TO=20'2002-01-01'=0A+=20=20WHERE=20id=20=3D=201;=0A+SELECT=20= tableoid::regclass,=20*=20FROM=20temporal_parent=20ORDER=20BY=20= valid_at;=0A+=20tableoid=20|=20id=20|=20=20=20=20=20=20=20=20valid_at=20=20= =20=20=20=20=20=20=20|=20name=20=0A= +----------+----+-------------------------+------=0A+=20mi_child=20|=20=20= 1=20|=20[2000-01-01,2001-01-01)=20|=20old=0A+=20mi_child=20|=20=201=20|=20= [2002-01-01,2010-01-01)=20|=20old=0A+(2=20rows)=0A+=0A+SELECT=20*=20FROM=20= mi_child=20ORDER=20BY=20valid_at;=0A+=20prefix=20|=20note=20|=20id=20|=20= =20=20=20=20=20=20=20valid_at=20=20=20=20=20=20=20=20=20|=20name=20=0A= +--------+------+----+-------------------------+------=0A+=20pfx=20=20=20= =20|=20memo=20|=20=201=20|=20[2000-01-01,2001-01-01)=20|=20old=0A+=20pfx=20= =20=20=20|=20memo=20|=20=201=20|=20[2002-01-01,2010-01-01)=20|=20old=0A= +(2=20rows)=0A+=0A+SELECT=20*=20FROM=20ONLY=20temporal_parent=20ORDER=20= BY=20valid_at;=0A+=20id=20|=20valid_at=20|=20name=20=0A= +----+----------+------=0A+(0=20rows)=0A+=0A+DROP=20TABLE=20= temporal_parent=20CASCADE;=0A+NOTICE:=20=20drop=20cascades=20to=20table=20= mi_child=0A=20RESET=20datestyle;=0Adiff=20--git=20= a/src/test/regress/sql/for_portion_of.sql=20= b/src/test/regress/sql/for_portion_of.sql=0Aindex=20= 04e0dba6375..b1144a13782=20100644=0A---=20= a/src/test/regress/sql/for_portion_of.sql=0A+++=20= b/src/test/regress/sql/for_portion_of.sql=0A@@=20-1484,6=20+1484,54=20@@=20= SELECT=20*=20FROM=20fpo_inh_child=20ORDER=20BY=20valid_at;=0A=20--=20No=20= rows=20should=20have=20leaked=20into=20the=20parent.=0A=20SELECT=20*=20= FROM=20ONLY=20fpo_inh_parent=20ORDER=20BY=20valid_at;=0A=20=0A+TRUNCATE=20= fpo_inh_child,=20fpo_inh_parent;=0A+INSERT=20INTO=20fpo_inh_child=20(id,=20= valid_at,=20name,=20description)=20VALUES=0A+=20=20('[1,2)',=20= '[2018-01-01,2019-01-01)',=20'one',=20'initial');=0A+=0A+DELETE=20FROM=20= fpo_inh_parent=20FOR=20PORTION=20OF=20valid_at=20FROM=20'2018-04-01'=20= TO=20'2018-10-01';=0A+=0A+SELECT=20tableoid::regclass,=20*=20FROM=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+SELECT=20*=20FROM=20= fpo_inh_child=20ORDER=20BY=20valid_at;=0A+SELECT=20*=20FROM=20ONLY=20= fpo_inh_parent=20ORDER=20BY=20valid_at;=0A+=0A=20DROP=20TABLE=20= fpo_inh_parent=20CASCADE;=0A=20=0A+--=20UPDATE=20FOR=20PORTION=20OF=20= with=20multiple=20inheritance=0A+--=20Leftover=20rows=20must=20stay=20in=20= the=20child=20table,=20even=20if=20the=20range=20column's=0A+--=20attnum=20= differs=20between=20the=20target=20parent=20and=20child.=0A+CREATE=20= TABLE=20temporal_parent=20(=0A+=20=20id=20int,=0A+=20=20valid_at=20= daterange,=0A+=20=20name=20text=0A+);=0A+CREATE=20TABLE=20other_parent=20= (=0A+=20=20prefix=20text,=0A+=20=20note=20text=0A+);=0A+CREATE=20TABLE=20= mi_child=20()=20INHERITS=20(other_parent,=20temporal_parent);=0A+=0A= +INSERT=20INTO=20mi_child=20(prefix,=20note,=20id,=20valid_at,=20name)=20= VALUES=0A+=20=20('pfx',=20'memo',=201,=20daterange('2000-01-01',=20= '2010-01-01'),=20'old');=0A+=0A+UPDATE=20temporal_parent=20FOR=20PORTION=20= OF=20valid_at=20FROM=20'2001-01-01'=20TO=20'2002-01-01'=0A+=20=20SET=20= name=20=3D=20'new'=0A+=20=20WHERE=20id=20=3D=201;=0A+=0A+SELECT=20= tableoid::regclass,=20*=20FROM=20temporal_parent=20ORDER=20BY=20= valid_at;=0A+SELECT=20*=20FROM=20mi_child=20ORDER=20BY=20valid_at;=0A= +SELECT=20*=20FROM=20ONLY=20temporal_parent=20ORDER=20BY=20valid_at;=0A+=0A= +TRUNCATE=20mi_child,=20other_parent,=20temporal_parent;=0A+INSERT=20= INTO=20mi_child=20(prefix,=20note,=20id,=20valid_at,=20name)=20VALUES=0A= +=20=20('pfx',=20'memo',=201,=20daterange('2000-01-01',=20'2010-01-01'),=20= 'old');=0A+=0A+DELETE=20FROM=20temporal_parent=20FOR=20PORTION=20OF=20= valid_at=20FROM=20'2001-01-01'=20TO=20'2002-01-01'=0A+=20=20WHERE=20id=20= =3D=201;=0A+=0A+SELECT=20tableoid::regclass,=20*=20FROM=20= temporal_parent=20ORDER=20BY=20valid_at;=0A+SELECT=20*=20FROM=20mi_child=20= ORDER=20BY=20valid_at;=0A+SELECT=20*=20FROM=20ONLY=20temporal_parent=20= ORDER=20BY=20valid_at;=0A+=0A+DROP=20TABLE=20temporal_parent=20CASCADE;=0A= +=0A=20RESET=20datestyle;=0A--=20=0A2.50.1=20(Apple=20Git-155)=0A=0A= --Apple-Mail=_69E186E3-7BA3-4F0D-AF51-377E8FE410AB--