From 206ac27e7567bba2aaacb6786f1402339714286c Mon Sep 17 00:00:00 2001 From: Ashvin Agrawal Date: Tue, 6 Dec 2022 12:19:28 -0800 Subject: [PATCH 1/3] feat: add proto converters and visitor This change adds some more logic to the substrait client. 1) it adds logic to map proto messages to domain objects for relations and expressions. 2) it adds a high level visitor control flow. This commit also introduces a lineage extractor application to drive development and testing of the control flow. For the testing it leverages pre-constructed substrait plans. --- .../Expression/FieldReference.cs | 9 + .../Expression/RelExpression.cs | 14 ++ src/Substrait.Core/ProtoConverter.cs | 154 ++++++++++++++++++ src/Substrait.Core/Relation/Cross.cs | 9 + src/Substrait.Core/Relation/Fetch.cs | 1 + src/Substrait.Core/Relation/Join.cs | 58 ++++++- src/Substrait.Core/Relation/Rel.cs | 12 ++ src/Substrait.Core/SubstraitRelVisitor.cs | 6 +- .../LineageExtractorRelVisitor.cs | 20 +++ .../Substrait.Lineage.csproj | 13 ++ substrait-csharp.sln | 18 ++ .../Relation/ProtoConverterTests.cs | 27 +++ .../Substrait.Core.Tests.csproj | 22 +++ tests/Substrait.Core.Tests/Usings.cs | 1 + .../LineageExtractorVisitorTest.cs | 19 +++ .../Substrait.Lineage.Tests.csproj | 27 +++ .../TestData/tpcds/Q02.pb | Bin 0 -> 3459 bytes tests/Substrait.Lineage.Tests/Usings.cs | 1 + 18 files changed, 406 insertions(+), 5 deletions(-) create mode 100644 src/Substrait.Core/Expression/FieldReference.cs create mode 100644 src/Substrait.Core/Expression/RelExpression.cs create mode 100644 src/Substrait.Core/ProtoConverter.cs create mode 100644 src/Substrait.Core/Relation/Cross.cs create mode 100644 src/Substrait.Lineage/LineageExtractorRelVisitor.cs create mode 100644 src/Substrait.Lineage/Substrait.Lineage.csproj create mode 100644 tests/Substrait.Core.Tests/Relation/ProtoConverterTests.cs create mode 100644 tests/Substrait.Core.Tests/Substrait.Core.Tests.csproj create mode 100644 tests/Substrait.Core.Tests/Usings.cs create mode 100644 tests/Substrait.Lineage.Tests/LineageExtractorVisitorTest.cs create mode 100644 tests/Substrait.Lineage.Tests/Substrait.Lineage.Tests.csproj create mode 100644 tests/Substrait.Lineage.Tests/TestData/tpcds/Q02.pb create mode 100644 tests/Substrait.Lineage.Tests/Usings.cs diff --git a/src/Substrait.Core/Expression/FieldReference.cs b/src/Substrait.Core/Expression/FieldReference.cs new file mode 100644 index 0000000..e706972 --- /dev/null +++ b/src/Substrait.Core/Expression/FieldReference.cs @@ -0,0 +1,9 @@ +namespace Substrait.Expression +{ + /// + /// The FIELD_REFERENCE relational expression, + /// + public class FieldReference : RelExpression + { + } +} diff --git a/src/Substrait.Core/Expression/RelExpression.cs b/src/Substrait.Core/Expression/RelExpression.cs new file mode 100644 index 0000000..b579d78 --- /dev/null +++ b/src/Substrait.Core/Expression/RelExpression.cs @@ -0,0 +1,14 @@ +using Substrait.Relation; + +namespace Substrait.Expression +{ + /// + /// Base type for all relational expressions, + /// + abstract public class RelExpression + { + public virtual void Accept(SubstraitRelVisitor visitor) + { + } + } +} diff --git a/src/Substrait.Core/ProtoConverter.cs b/src/Substrait.Core/ProtoConverter.cs new file mode 100644 index 0000000..2758a83 --- /dev/null +++ b/src/Substrait.Core/ProtoConverter.cs @@ -0,0 +1,154 @@ +using Substrait.Expression; +using Substrait.Protobuf; +using Substrait.Relation; +using System.Collections.Immutable; +using ProtoRel = Substrait.Protobuf.Rel; +using ProtoRex = Substrait.Protobuf.Expression; +using Rel = Substrait.Relation.Rel; + +namespace Substrait.Core +{ + /// + /// Utility to convert Substrait protobuf messages to/from charp domain-objects. + /// + public class ProtoConverter + { + /// + /// Create domain object specific to relational operator type from protobuf message + /// + /// Relation encoded as protobuf message + /// corresponding to message's operator type + public Rel ToRel(ProtoRel protoRel) + { + var relType = protoRel.RelTypeCase; + + return relType switch + { + ProtoRel.RelTypeOneofCase.Aggregate => CreateAgg(protoRel.Aggregate), + ProtoRel.RelTypeOneofCase.Cross => CreateCross(protoRel.Cross), + ProtoRel.RelTypeOneofCase.Fetch => CreateFetch(protoRel.Fetch), + ProtoRel.RelTypeOneofCase.Filter => CreateFilter(protoRel.Filter), + ProtoRel.RelTypeOneofCase.Join => CreateJoin(protoRel.Join), + ProtoRel.RelTypeOneofCase.Project => CreateProject(protoRel.Project), + ProtoRel.RelTypeOneofCase.Read => CreateRead(protoRel.Read), + ProtoRel.RelTypeOneofCase.Sort => CreateSort(protoRel.Sort), + _ => throw new NotImplementedException(relType.ToString()), + }; + } + + /// + /// Create domain object specific to relational expression type from protobuf message + /// + /// Relational expression encoded as protobuf message + /// corresponding to message's expression type + private RelExpression ToExpression(ProtoRex protoRex) + { + var rexType = protoRex.RexTypeCase; + + return rexType switch + { + ProtoRex.RexTypeOneofCase.Selection => CreateFieldReference(protoRex.Selection), + ProtoRex.RexTypeOneofCase.None => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.Literal => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.ScalarFunction => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.WindowFunction => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.IfThen => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.SwitchExpression => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.SingularOrList => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.MultiOrList => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.Cast => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.Subquery => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.Nested => throw new NotImplementedException(), + ProtoRex.RexTypeOneofCase.Enum => throw new NotImplementedException(), + _ => throw new NotImplementedException(rexType.ToString()), + }; + } + + private Rel CreateAgg(AggregateRel agg) + { + var input = ToRel(agg.Input); + var inputs = ImmutableList.Create(input); + return new Aggregate() + { + Inputs = inputs, + }; + } + + private Rel CreateCross(CrossRel cross) + { + var left = ToRel(cross.Left); + var right = ToRel(cross.Right); + var inputs = ImmutableList.Create(left, right); + return new Cross() + { + Inputs = inputs, + }; + } + + private Rel CreateFetch(FetchRel fetch) + { + var input = ToRel(fetch.Input); + var inputs = ImmutableList.Create(input); + return new Fetch() + { + Count = fetch.Count, + Inputs = inputs, + }; + } + + private Rel CreateFilter(FilterRel filter) + { + var input = ToRel(filter.Input); + var inputs = ImmutableList.Create(input); + return new Filter() + { + Inputs = inputs, + }; + } + + private Rel CreateJoin(JoinRel join) + { + var left = ToRel(join.Left); + var right = ToRel(join.Right); + var _ = ToExpression(join.Expression); + var inputs = ImmutableList.Create(left, right); + return new Join() + { + Inputs = inputs, + }; + } + + private Rel CreateProject(ProjectRel project) + { + var input = ToRel(project.Input); + var inputs = ImmutableList.Create(input); + return new Join() + { + Inputs = inputs, + }; + } + + private Rel CreateRead(ReadRel read) + { + return new Read() + { + Inputs = ImmutableList.Empty, + }; + } + + private Rel CreateSort(SortRel sort) + { + var input = ToRel(sort.Input); + var inputs = ImmutableList.Create(input); + return new Sort() + { + Inputs = inputs, + }; + } + + private RelExpression CreateFieldReference(ProtoRex.Types.FieldReference field) + { + return new FieldReference(); + } + } +} diff --git a/src/Substrait.Core/Relation/Cross.cs b/src/Substrait.Core/Relation/Cross.cs new file mode 100644 index 0000000..0cad61d --- /dev/null +++ b/src/Substrait.Core/Relation/Cross.cs @@ -0,0 +1,9 @@ +namespace Substrait.Relation +{ + /// + /// The CROSS relational operator representing cartesian product, + /// + public class Cross : Rel + { + } +} diff --git a/src/Substrait.Core/Relation/Fetch.cs b/src/Substrait.Core/Relation/Fetch.cs index 4ce5e36..84b1b18 100644 --- a/src/Substrait.Core/Relation/Fetch.cs +++ b/src/Substrait.Core/Relation/Fetch.cs @@ -5,5 +5,6 @@ /// public class Fetch : Rel { + public long Count { get; init; } } } diff --git a/src/Substrait.Core/Relation/Join.cs b/src/Substrait.Core/Relation/Join.cs index 0289d8a..72dc802 100644 --- a/src/Substrait.Core/Relation/Join.cs +++ b/src/Substrait.Core/Relation/Join.cs @@ -1,9 +1,65 @@ -namespace Substrait.Relation +using Substrait.Expression; +using Substrait.Protobuf; + +namespace Substrait.Relation { /// /// The binary JOIN relational operator, /// public class Join : Rel { + public RelExpression? Condition { get; init; } + public RelExpression? PostJoinFilter { get; init; } + public JoinType JoinType { get; init; } = JoinType.UNKNOWN; + + public override void Accept(SubstraitRelVisitor visitor) + { + base.Accept(visitor); + Condition?.Accept(visitor); + PostJoinFilter?.Accept(visitor); + } + } + + public enum JoinType + { + /// + /// + /// + ANTI, + + /// + /// + /// + INNER, + + /// + /// + /// + LEFT, + + /// + /// + /// + OUTER, + + /// + /// + /// + RIGHT, + + /// + /// + /// + SEMI, + + /// + /// + /// + SINGLE, + + /// + /// + /// + UNKNOWN } } diff --git a/src/Substrait.Core/Relation/Rel.cs b/src/Substrait.Core/Relation/Rel.cs index 8730c30..13fbfe5 100644 --- a/src/Substrait.Core/Relation/Rel.cs +++ b/src/Substrait.Core/Relation/Rel.cs @@ -5,5 +5,17 @@ /// abstract public class Rel { + /// + /// Input relations to this relation + /// + public IList Inputs { get; init; } = new List(); + + public virtual void Accept(SubstraitRelVisitor visitor) + { + foreach (var input in Inputs) + { + input.Accept(visitor); + } + } } } diff --git a/src/Substrait.Core/SubstraitRelVisitor.cs b/src/Substrait.Core/SubstraitRelVisitor.cs index 3a48f12..361fd69 100644 --- a/src/Substrait.Core/SubstraitRelVisitor.cs +++ b/src/Substrait.Core/SubstraitRelVisitor.cs @@ -1,6 +1,4 @@ -using Substrait.Relation; - -namespace Substrait.Core +namespace Substrait.Relation { /// /// Visitor to transform, compile, and/or process SQL logical operators represented using Substrait. The visitor has @@ -99,7 +97,7 @@ public void Visit(Sort sort) Fallback(sort); } - public void Fallback(Rel _) + protected void Fallback(object _) { throw new InvalidOperationException(); } diff --git a/src/Substrait.Lineage/LineageExtractorRelVisitor.cs b/src/Substrait.Lineage/LineageExtractorRelVisitor.cs new file mode 100644 index 0000000..8af2dc4 --- /dev/null +++ b/src/Substrait.Lineage/LineageExtractorRelVisitor.cs @@ -0,0 +1,20 @@ +using Substrait.Core; +using Substrait.Relation; +using ProtoRel = Substrait.Protobuf.Rel; + +namespace Substrait.Lineage +{ + /// + /// A concrete implementation of for processing Substrait relations and extracting + /// lineage information. + /// + public class LineageExtractorRelVisitor : SubstraitRelVisitor + { + public void Execute(ProtoRel protoRel) + { + ProtoConverter converter = new(); + var rel = converter.ToRel(protoRel); + rel.Accept(this); + } + } +} diff --git a/src/Substrait.Lineage/Substrait.Lineage.csproj b/src/Substrait.Lineage/Substrait.Lineage.csproj new file mode 100644 index 0000000..c93dd2c --- /dev/null +++ b/src/Substrait.Lineage/Substrait.Lineage.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/substrait-csharp.sln b/substrait-csharp.sln index 7efe320..42989cf 100644 --- a/substrait-csharp.sln +++ b/substrait-csharp.sln @@ -5,6 +5,12 @@ VisualStudioVersion = 17.3.33027.108 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrait.Core", "src\Substrait.Core\Substrait.Core.csproj", "{C33A4305-4A80-4A92-AEF5-FB304D8BA6C7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrait.Lineage", "src\Substrait.Lineage\Substrait.Lineage.csproj", "{365DAF8C-5336-4845-A297-38584F4DB328}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Substrait.Lineage.Tests", "tests\Substrait.Lineage.Tests\Substrait.Lineage.Tests.csproj", "{060D3D24-9395-4C8D-8C0C-95EDF2A86931}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Substrait.Core.Tests", "tests\Substrait.Core.Tests\Substrait.Core.Tests.csproj", "{590A26FC-0099-4A5E-8833-8D6CF5814C51}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +21,18 @@ Global {C33A4305-4A80-4A92-AEF5-FB304D8BA6C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {C33A4305-4A80-4A92-AEF5-FB304D8BA6C7}.Release|Any CPU.ActiveCfg = Release|Any CPU {C33A4305-4A80-4A92-AEF5-FB304D8BA6C7}.Release|Any CPU.Build.0 = Release|Any CPU + {365DAF8C-5336-4845-A297-38584F4DB328}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {365DAF8C-5336-4845-A297-38584F4DB328}.Debug|Any CPU.Build.0 = Debug|Any CPU + {365DAF8C-5336-4845-A297-38584F4DB328}.Release|Any CPU.ActiveCfg = Release|Any CPU + {365DAF8C-5336-4845-A297-38584F4DB328}.Release|Any CPU.Build.0 = Release|Any CPU + {060D3D24-9395-4C8D-8C0C-95EDF2A86931}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {060D3D24-9395-4C8D-8C0C-95EDF2A86931}.Debug|Any CPU.Build.0 = Debug|Any CPU + {060D3D24-9395-4C8D-8C0C-95EDF2A86931}.Release|Any CPU.ActiveCfg = Release|Any CPU + {060D3D24-9395-4C8D-8C0C-95EDF2A86931}.Release|Any CPU.Build.0 = Release|Any CPU + {590A26FC-0099-4A5E-8833-8D6CF5814C51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {590A26FC-0099-4A5E-8833-8D6CF5814C51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {590A26FC-0099-4A5E-8833-8D6CF5814C51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {590A26FC-0099-4A5E-8833-8D6CF5814C51}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tests/Substrait.Core.Tests/Relation/ProtoConverterTests.cs b/tests/Substrait.Core.Tests/Relation/ProtoConverterTests.cs new file mode 100644 index 0000000..44f8910 --- /dev/null +++ b/tests/Substrait.Core.Tests/Relation/ProtoConverterTests.cs @@ -0,0 +1,27 @@ +using Substrait.Core; +using Substrait.Protobuf; + +namespace Substrait.Relation.Tests +{ + [TestClass()] + public class ProtoConverterTests + { + [TestMethod()] + public void ToRel_FetchRel_Test() + { + FetchRel fetchRel = new FetchRel(); + fetchRel.Count = 1; // limit 1 + var rel = new Protobuf.Rel() + { + Fetch = fetchRel + }; + + fetchRel.Input = rel; + + ProtoConverter converter = new(); + var result = converter.ToRel(rel) as Fetch; + Assert.IsNotNull(result); + Assert.AreEqual(1, result.Count); + } + } +} \ No newline at end of file diff --git a/tests/Substrait.Core.Tests/Substrait.Core.Tests.csproj b/tests/Substrait.Core.Tests/Substrait.Core.Tests.csproj new file mode 100644 index 0000000..29b0b9a --- /dev/null +++ b/tests/Substrait.Core.Tests/Substrait.Core.Tests.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + diff --git a/tests/Substrait.Core.Tests/Usings.cs b/tests/Substrait.Core.Tests/Usings.cs new file mode 100644 index 0000000..ab67c7e --- /dev/null +++ b/tests/Substrait.Core.Tests/Usings.cs @@ -0,0 +1 @@ +global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file diff --git a/tests/Substrait.Lineage.Tests/LineageExtractorVisitorTest.cs b/tests/Substrait.Lineage.Tests/LineageExtractorVisitorTest.cs new file mode 100644 index 0000000..04927d1 --- /dev/null +++ b/tests/Substrait.Lineage.Tests/LineageExtractorVisitorTest.cs @@ -0,0 +1,19 @@ +using Substrait.Protobuf; + +namespace Substrait.Lineage.Tests +{ + [TestClass] + public class LineageExtractorVisitorTest + { + [TestMethod] + public void TestMethod1() + { + Plan plan; + using var planPb = File.OpenRead(@"TestData\tpcds\Q02.pb"); + plan = Plan.Parser.ParseFrom(planPb); + + var lineageVisitor = new LineageExtractorRelVisitor(); + lineageVisitor.Execute(plan.Relations[0].Root.Input); + } + } +} \ No newline at end of file diff --git a/tests/Substrait.Lineage.Tests/Substrait.Lineage.Tests.csproj b/tests/Substrait.Lineage.Tests/Substrait.Lineage.Tests.csproj new file mode 100644 index 0000000..5ab0847 --- /dev/null +++ b/tests/Substrait.Lineage.Tests/Substrait.Lineage.Tests.csproj @@ -0,0 +1,27 @@ + + + + net6.0 + enable + enable + + false + + + + + + + + + + + + + + + + + + + diff --git a/tests/Substrait.Lineage.Tests/TestData/tpcds/Q02.pb b/tests/Substrait.Lineage.Tests/TestData/tpcds/Q02.pb new file mode 100644 index 0000000000000000000000000000000000000000..721a3a4c55d205feb2193edc7ec5ef5cc3ebb6a2 GIT binary patch literal 3459 zcmc&$+iM(E7|+a3b|)vh+0AU*Y)++3S1F|rURp&6`Y@e2*$kaqW@eLYeHb^Fwt-w~ znhJgON$_3pN%64=O2yloC`b!M!3Q4%5k;{Gf`5X)b7p2|HW%ZY57~T|-}imzobNW| zj9Sv@GuQ8IukLN^Y~POiyBm8qx7PPIR-eAx-`XUnRY{vF=vQ`jHrM;xiSoRvXzhYB zH;&iVS2wo$n+fiWDh~x&-PyVY?CqVzk2XQ8szlZP_S!7>ubre#Rc=VMw*K0k{^o3d z`)-UstxjvI)R1XqXE(t$>7-g}l<0W>^&7K0xAx+V%a=4RR2oVy#8K!w)7sn9! zt3_loqW#vo_)9`PYPBCG)Q3~EA54)ktwKiEuiv=2q5XPF`}vfBzu#PWw<)O4>noqs z1@-m#%9rDU`m?<9M_EwcE95&xP+usd9)@w~*=B6&5sSmCxgfF}As|3l5p%e50<_T$ zBhO(0=f^p3GRMo9`HbOKx@itjunB}aZsG@CV$uK;S;kcs#ctQR!UExOp{u)*74^s@ z)JyZ8%|hK~vEhXgsX=60VFVwR!Nh^MlKbR*6Kb{`#ikV+Ue}Fc-HC{n3X8y#scfHn z9+BG@Lhze#QKT=6=AFu3=D)Y@aC*Ydms_zB8sN)D;MaZ z{2-kn$G(!vsJzOIME)yMtal@NfRPwb`3qU@TRHo1cZJ!Fy{4;#VkZ2qBcnbQX^od6~zJIZiiGMF`19T zK&Hvblw*!>dp!oQ5OZe<$hKLBR}sLPDPCPBm3xw+N-b$0aRQPgQ35~)Y$1DigDC{f zx`E%f6X^cDWrXyRLLMe9_NhX~^5)7&luJ30l5xC==SK5!$QB4O<0Zzf3c6;-XoMi* zody-~J*Ed_6n5Sc|L1tUgmd`61#oab*GpgxK^7grACv?42xaQM*wr0$Q65V0@Pn?i zpyw{R2@*(}aNyatw}iJJ=yCixD?mS*p2LrC>nV+JA$*GB{ieN0Ol5$2ItQ#&l z%J~tccBm8779pw_$)@Gd$0hQ6Ni^3FB{F6W#&JfXoElafFoSncz@HTTGLcA-xr852 z?MxOLq;3r!JQDpoj@KA#io6BR1Ku1px&28)d&2^51*Wcp1(9mrAXZItbp;saRkAKh*0IzB=d}Pmx;oc zEd8lOeoRvRO^FacUzGzI*RK18MDx{K^W!YfoE`HAB~s?&5qopeM}34?To|dSkq(PU zHS;cd9zHQ}U6FActgJc3G1aOfFkYC;QFoAPXv{4? zfDcf9%q)hFu? z8d=K{T+awtA+_VU0{`IQD~^6#q92tgc0)sIpQlgJHohqnj!;#@2bwn09%)x8(Nv;n zvN{9q0tGU~$pxJ}gnVfqQYs*oA>`D*Ak`sc01juQGlNs+Cu>2cQq=7|Nt!znHC;e0 zwO^z!(94JTqClOd)7Pf5=8?53A@`(;zl#s_-Mj5&x=15cPM_+iBfU}x<{o*ZSBFqf z(sT6eAxAn7RE3U`(uHs9gKWIq9vRT2KvxTNvq0B4P4c`xfh3n^N*6^LJ}b@UuPGti vIdWE2pv`B~5QL}u7)a@O2ugug^CLCnnKdonBbuUjI?svUOXByk_ Date: Thu, 8 Dec 2022 19:54:19 -0800 Subject: [PATCH 2/3] fix: use consistent naming for relations Co-authored-by: Weston Pace --- src/Substrait.Core/ProtoConverter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Substrait.Core/ProtoConverter.cs b/src/Substrait.Core/ProtoConverter.cs index 2758a83..02f89b0 100644 --- a/src/Substrait.Core/ProtoConverter.cs +++ b/src/Substrait.Core/ProtoConverter.cs @@ -14,10 +14,10 @@ namespace Substrait.Core public class ProtoConverter { /// - /// Create domain object specific to relational operator type from protobuf message + /// Create domain object from a protobuf encoded message /// /// Relation encoded as protobuf message - /// corresponding to message's operator type + /// corresponding to message's relation public Rel ToRel(ProtoRel protoRel) { var relType = protoRel.RelTypeCase; From 52b365e391f17af3125b86c7b496a6934fea378d Mon Sep 17 00:00:00 2001 From: Ashvin Agrawal Date: Thu, 15 Dec 2022 09:29:57 -0800 Subject: [PATCH 3/3] fix: match rel type and resolve review comment --- src/Substrait.Core/ProtoConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Substrait.Core/ProtoConverter.cs b/src/Substrait.Core/ProtoConverter.cs index 02f89b0..24f782d 100644 --- a/src/Substrait.Core/ProtoConverter.cs +++ b/src/Substrait.Core/ProtoConverter.cs @@ -122,7 +122,7 @@ private Rel CreateProject(ProjectRel project) { var input = ToRel(project.Input); var inputs = ImmutableList.Create(input); - return new Join() + return new Project() { Inputs = inputs, };