> All of these approaches are aligned in one, specific way: the storage table is an iceberg table.
I do not think that is true. I think people are aligned that we would like to re-use the Iceberg table metadata defined in the Iceberg table spec to express the data in MV, but I don't think it goes that far to say it must be an Iceberg table. Once you have that mindset, then of course option 1 (separate table and view) is the only option. > I don't think that is necessary and it significantly increases the complexity. And can you quantify what you mean by "significantly increases the complexity"? Seems like a lot of concerns are coming from the tradeoff with complexity. We probably all agree that using option 7 (a completely new metadata type) is a lot of work from scratch, that is why it is not favored. However, my understanding is that as long as we re-use the view and table metadata, then the majority of the existing logic can be reused. I think what we have gone through in Slack to draft the rough Java API shape helps here, because people can estimate the amount of effort required to implement it. And I don't think they are **significantly** more complex to implement. Could you elaborate more about the complexity that you imagine? -Jack On Fri, Mar 1, 2024 at 8:57 AM Daniel Weeks <daniel.c.we...@gmail.com> wrote: > I feel I've been most vocal about pushing back against options 2+ (or > Ryan's categories of combined table/view, or new metadata type), so I'll > try to expand on my reasoning. > > I understand the appeal of creating a design where we encapsulate the > view/storage from both a structural and performance standpoint, but I don't > think that is necessary and it significantly increases the complexity. > > All of these approaches are aligned in one, specific way: the storage > table is an iceberg table. > > Because of this, all the behaviors and requirements still apply to these > tables. They need to be maintained (snapshot cleanup, orphan files), in > cases need to be optimized (compaction, manifest rewrites), they need to be > able to be inspected (this will be even more important with MV since > staleness can produce different results and questions will arise about what > state the storage table was in). There may be cases where the tables need > to be managed directly. > > Anywhere we deviate from the existing constructs/commit/access for tables, > we will ultimately have to then unwrap to re-expose the underlying Iceberg > behavior. This creates unnecessary complexity in the library/API layer, > which are not the primary interface users will have with materialized views > where an engine is almost entirely necessary to interact with the dataset. > > As to the performance concerns around option 1, I think we're overstating > the downsides. It really comes down to how many metadata loads are > necessary and evaluating freshness would likely be the real bottleneck as > it involves potentially loading many tables. All of the options are on the > same order of performance for the metadata and table loads. > > As to the visibility of tables and whether they're registered in the > catalog, I think registering in the catalog is the right approach so that > the tables are still addressable for maintenance/etc. The visibility of > the storage table is a catalog implementation decision and shouldn't be a > requirement of the MV spec (I can see cases for both and it isn't necessary > to dictate a behavior). > > I'm still strongly in favor of Option 1 (separate table and view) for > these reasons. > > -Dan > > > > On Thu, Feb 29, 2024 at 11:07 PM Jack Ye <yezhao...@gmail.com> wrote: > >> > Jack, it sounds like you’re the proponent of a combined table and view >> (rather than a new metadata spec for a materialized view). What is the main >> motivation? It seems like you’re convinced of that approach, but I don’t >> understand the advantage it brings. >> >> Sorry I have to make a Google Sheet to capture all the options we have >> discussed so far, I wanted to use the existing Google Doc, but it has >> really bad table/sheet support... >> >> >> https://docs.google.com/spreadsheets/d/1a0tlyh8f2ft2SepE7H3bgoY2A0q5IILgzAsJMnwjTBs/edit#gid=0 >> >> I have listed all the options, with how they are implemented and some >> important considerations we have discussed so far. Note that: >> 1. This sheet currently excludes the lineage information, which we can >> discuss more later after the current topic is resolved. >> 2. I removed the considerations for REST integration since from the other >> thread we have clarified that they should be considered completely >> separately. >> >> *Why I come as a proponent of having a new MV object with table and view >> metadata file pointer* >> >> In my sheet, there are 3 options that do not have major problems: >> Option 2: Add storage table metadata file pointer in view object >> Option 5: New MV object with table and view metadata file pointer >> Option 6: New MV spec with table and view metadata >> >> I originally excluded option 2 because I think it does not align with the >> REST spec, but after the other discussion thread about "Inconsistency >> between REST spec and table/view spec", I think my original concern no >> longer holds true so now I put it back. And based on my personal >> preference that MV is an independent object that should be separated from >> view and table, plus the fact that option 5 is probably less work than >> option 6 for implementation, that is how I come as a proponent of option 5 >> at this moment. >> >> >> *Regarding Ryan's evaluation framework* >> >> I think we need to reconcile this sheet with Ryan's evaluation framework. >> That framework categorization puts option 2, 3, 4, 5, 6 all under the same >> category of "A combination of a view and a table" and concludes that >> they don't have any advantage for the same set of reasons. But those >> reasons are not really convincing to me so let's talk about them in more >> detail. >> >> (1) You said "I don’t see a reason why a combined view and table is >> advantageous" as "this would cause unnecessary dependence between the view >> and table in catalogs." What dependency exactly do you mean here? And why >> is that unnecessary, given there has to be some sort of dependency anyway >> unless we go with option 5 or 6? >> >> (2) You said "I guess there’s an argument that you could load both table >> and view metadata locations at the same time. That hardly seems worth the >> trouble". I disagree with that. Catalog interaction performance is critical >> to at least everyone working in EMR and Athena, and MV itself as an >> acceleration approach needs to be as fast as possible. >> >> I have put 3 key operations in the doc that I think matters for MV during >> interactions with engine: >> 1. refreshes storage table >> 2. get the storage table of the MV >> 3. if stale, get the view SQL >> >> And option 1 clearly falls short with 4 sequential steps required to load >> a storage table. You mentioned "recent issues with adding views to the JDBC >> catalog" in this topic, could you explain a bit more? >> >> (3) You said "I also think that once we decide on structure, we can make >> it possible for REST catalog implementations to do smart things, in a way >> that doesn’t put additional requirements on the underlying catalog store." >> If REST is fully compatible with Iceberg spec then I have no problem with >> this statement. However, as we discussed in the other thread, it is not the >> case. In the current state, I think the sequence of action should be to >> evolve the Iceberg table/view spec (or add a MV spec) first, and then think >> about how REST can incorporate it or do smart things that are not Iceberg >> spec compliant. Do you agree with that? >> >> (4) You said the table identifier pointer "is a problem we need to solve >> generally because a materialized table needs to be able to track the >> upstream state of tables that were used". I don't think that is a reason to >> choose to use a table identifier pointer for a storage table. The issue is >> not about using a table identifier pointer. It is about exposing the >> storage table as a separate entity in the catalog, which is what people do >> not like and is already discussed in length in Jan's question 3 (also >> linked in the sheet). I agree with that statement, because without a REST >> implementation that can magically hide the storage table, this model adds >> additional burden regarding compliance and data governance for any other >> non-REST catalog implementations that are compliant to the Iceberg spec. >> Many mechanisms need to be built in a catalog to hide, protect, maintain, >> recycle the storage table, that can be avoided by using other approaches. I >> think we should reach a consensus about that and discuss further if you do >> not agree. >> >> Best, >> Jack Ye >> >> On Thu, Feb 29, 2024 at 10:53 PM Jan Kaul <jank...@mailbox.org.invalid> >> wrote: >> >>> Hi Ryan, we actually discussed your categories in this question >>> <https://docs.google.com/document/d/1UnhldHhe3Grz8JBngwXPA6ZZord1xMedY5ukEhZYF-A/edit?pli=1#heading=h.y70rtfhi9qxi>. >>> Where your categories correspond to the following designs: >>> >>> - Separate table and view => Design 1 >>> - Combination of view and table => Design 2 >>> - A new metadata type => Design 4 >>> >>> Jan >>> On 01.03.24 00:03, Ryan Blue wrote: >>> >>> Looks like it wasn’t clear what I meant for the 3 categories, so I’ll be >>> more specific: >>> >>> - *Separate table and view*: this option is to have the objects that >>> we have today, with extra metadata. Commit processes are separate: >>> committing to the table doesn’t alter the view and committing to the view >>> doesn’t change the table. However, changing the view can make it so the >>> table is no longer useful as a materialization. >>> - *A combination of a view and a table*: in this option, the table >>> metadata and view metadata are the same as the first option. The >>> difference >>> is that the commit process combines them, either by embedding a table >>> metadata location in view metadata or by tracking both in the same >>> catalog >>> reference. >>> - *A new metadata type*: this option is where we define a new >>> metadata object that has view attributes, like SQL representations, along >>> with table attributes, like partition specs and snapshots. >>> >>> Hopefully this is clear because I think much of the confusion is caused >>> by different definitions. >>> >>> The LoadTableResponse having optional metadata-location field implies >>> that the object in the catalog no longer needs to hold a metadata file >>> pointer >>> >>> The REST protocol has not removed the requirement for a metadata file, >>> so I’m going to keep focused on the MV design options. >>> >>> When we say a MV can be a “new metadata type”, it does not mean it needs >>> to define a completely brand new structure of the metadata content >>> >>> I’m making a distinction between separate metadata files for the table >>> and the view and a combined metadata object, as above. >>> >>> We can define an “Iceberg MV” to be an object in a catalog, which has 1 >>> table metadata file pointer, and 1 view metadata file pointer >>> >>> This is the option I am referring to as a “combination of a view and a >>> table”. >>> >>> So to review my initial email, I don’t see a reason why a combined view >>> and table is advantageous, either implemented by having a catalog reference >>> with two metadata locations or embedding a table metadata location in view >>> metadata. This would cause unnecessary dependence between the view and >>> table in catalogs. I guess there’s an argument that you could load both >>> table and view metadata locations at the same time. That hardly seems worth >>> the trouble given the recent issues with adding views to the JDBC catalog. >>> >>> I also think that once we decide on structure, we can make it possible >>> for REST catalog implementations to do smart things, in a way that doesn’t >>> put additional requirements on the underlying catalog store. For instance, >>> we could specify how to send additional objects in a LoadViewResult, in >>> case the catalog wants to pre-fetch table metadata. I think these >>> optimizations are a later addition, after we define the relationship >>> between views and tables. >>> >>> Jack, it sounds like you’re the proponent of a combined table and view >>> (rather than a new metadata spec for a materialized view). What is the main >>> motivation? It seems like you’re convinced of that approach, but I don’t >>> understand the advantage it brings. >>> >>> Ryan >>> >>> On Thu, Feb 29, 2024 at 12:26 PM Szehon Ho <szehon.apa...@gmail.com> >>> wrote: >>> >>>> Hi >>>> >>>> Yes I mostly agree with the assessment. To clarify a few minor points. >>>> >>>> is a materialized view a view and a separate table, a combination of >>>>> the two (i.e. commits are combined), or a new metadata type? >>>> >>>> >>>> For 'new metadata type', I consider mostly Jack's initial proposal of a >>>> new Catalog MV object that has two references (ViewMetadata + >>>> TableMetadata). >>>> >>>> The arguments that I see for a combined materialized view object are: >>>>> >>>>> - Regular views are separate, rather than being tables with SQL >>>>> and no data so it would be inconsistent (“Iceberg view is just a table >>>>> with >>>>> no data but with representations defined. But we did not do that.”) >>>>> >>>>> >>>>> - Materialized views are different objects in DDL >>>>> >>>>> >>>>> - Tables may be a superset of functionality needed for >>>>> materialized views >>>>> >>>>> >>>>> - Tables are not typically exposed to end users — but this isn’t >>>>> required by the separate view and table option >>>>> >>>>> For completeness, there seem to be a few additional ones (mentioned in >>>> the Slack and above messages). >>>> >>>> - Lack of spec change (to ViewMetadata). But as Jack says it is a >>>> spec change (ie, to catalogs) >>>> - A single call to get the View's StorageTable (versus two calls) >>>> - A more natural API, no opportunity for user to call >>>> Catalog.dropTable() and renameTable() on storage table >>>> >>>> >>>> *Thoughts: *I think the long discussion sessions we had on Slack >>>> was fruitful for me, as seeing the API clarified some things. >>>> >>>> I was initially more in favor of MV being a new metadata type >>>> (TableMetadata + ViewMetadata). But seeing most of the MV operations end >>>> up being ViewCatalog or Catalog operations, I am starting to think API-wise >>>> that it may not align with the new metadata type (unless we define >>>> MVCatalog and /MV REST endpoints, which then are boilerplate wrappers). >>>> >>>> Initially one question I had for option 'a view and a separate table', >>>> was how to make this table reference (metadata.json or catalog reference). >>>> In the previous option, we had a precedent of Catalog references to >>>> Metadata, but not pointers between Metadatas. I initially saw the proposed >>>> Catalog's TableIdentifier pointer as 'polluting' catalog concerns in >>>> ViewMetadata. (I saw Catalog and ViewCatalog as a layer above >>>> TableMetadata and ViewMetadata). But I think Dan in the Slack made a fair >>>> point that ViewMetadata already is tightly bound with a Catalog. In this >>>> case, I think this approach does have its merits as well in aligning >>>> Catalog API's with the metadata. >>>> >>>> Thanks >>>> Szehon >>>> >>>> >>>> >>>> On Thu, Feb 29, 2024 at 5:45 AM Jan Kaul <jank...@mailbox.org.invalid> >>>> <jank...@mailbox.org.invalid> wrote: >>>> >>>>> Hi all, >>>>> >>>>> I would like to provide my perspective on the question of what a >>>>> materialized view is and elaborate on Jack's recent proposal to view a >>>>> materialized view as a catalog concept. >>>>> >>>>> Firstly, let's look at the role of the catalog. Every entity in the >>>>> catalog has a *unique identifier*, and the catalog provides methods >>>>> to create, load, and update these entities. An important thing to note is >>>>> that the catalog methods exhibit two different behaviors: the *create >>>>> and load methods deal with the entire entity*, while the *update(commit) >>>>> method only deals with partial changes* to the entities. >>>>> >>>>> In the context of our current discussion, materialized view (MV) >>>>> metadata is a union of view and table metadata. The fact that the update >>>>> method deals only with partial changes, enables us to *reuse the >>>>> existing methods for updating tables and views*. For updates we don't >>>>> have to define what constitutes an entire materialized view. Changes to a >>>>> materialized view targeting the properties related to the view metadata >>>>> could use the update(commit) view method. Similarly, changes targeting the >>>>> properties related to the table metadata could use the update(commit) >>>>> table >>>>> method. This is great news because we don't have to redefine view and >>>>> table >>>>> commits (requirements, updates). >>>>> This is shown in the fact that Jack uses the same operation to update >>>>> the storage table for Option 1 and 3: >>>>> >>>>> // REST: POST /namespaces/db1/tables/mv1?materializedView=true >>>>> // non-REST: update JSON files at table_metadata_location >>>>> storageTable.newAppend().appendFile(...).commit(); >>>>> >>>>> The open question is *whether the create and load methods should >>>>> treat the properties that constitute the MV metadata as two entities (View >>>>> + Table) or one entity (new MV object)*. This is all part of Jack's >>>>> proposal, where Option 1 proposes a new MV object, and Option 3 proposes >>>>> two separate entities. The advantage of Option 1 is that it doesn't >>>>> require >>>>> two operations to load the metadata. On the other hand, the advantage of >>>>> Option 3 is that no new operations or catalogs have to be defined. >>>>> >>>>> In my opinion, defining a new representation for materialized views >>>>> (Option 1) is generally the cleaner solution. However, I see a path where >>>>> we could first introduce Option 3 and still have the possibility to >>>>> transition to Option 1 if needed. The great thing about Option 3 is that >>>>> it >>>>> only requires minor changes to the current spec and is mostly >>>>> implementation detail. >>>>> >>>>> Therefore I would propose small additions to Jacks Option 3 that only >>>>> introduce changes to the spec that are not specific to materialized views. >>>>> The idea is to introduce boolean properties to be set on the creation of >>>>> the view and the storage table that indicate that they belong to a >>>>> materialized view. The view property "materialized" is set to "true" for a >>>>> MV and "false" for a regular view. And the table property "storage_table" >>>>> is set to "true" for a storage table and "false" for a regular table. The >>>>> absence of these properties indicates a regular view or table. >>>>> >>>>> ViewCatalog viewCatalog = (ViewCatalog) catalog; >>>>> >>>>> // REST: GET /namespaces/db1/views/mv1 >>>>> // non-REST: load JSON file at metadata_location >>>>> View mv = viewCatalog.loadView(TableIdentifier.of("db1", "mv1")); >>>>> >>>>> // REST: GET /namespaces/db1/tables/mv1 >>>>> // non-REST: load JSON file at table_metadata_location if present >>>>> Table storageTable = view.storageTable(); >>>>> >>>>> // REST: POST /namespaces/db1/tables/mv1 >>>>> // non-REST: update JSON file at table_metadata_location >>>>> storageTable.newAppend().appendFile(...).commit(); >>>>> >>>>> We could then introduce a new requirement for views and tables called >>>>> "AssertProperty" which could make sure to only perform updates that are >>>>> inline with materialized views. The additional requirement can be seen as >>>>> a >>>>> general extension which does not need to be changed if we decide to got >>>>> with Option 1 in the future. >>>>> >>>>> Let me know what you think. >>>>> >>>>> Best wishes, >>>>> >>>>> Jan >>>>> On 29.02.24 04:09, Walaa Eldin Moustafa wrote: >>>>> >>>>> Thanks Ryan for the insights. I agree that reusing existing metadata >>>>> definitions and minimizing spec changes are very important. This also >>>>> minimizes spec drift (between materialized views and views spec, and >>>>> between materialized views and tables spec), and simplifies the >>>>> implementation. >>>>> >>>>> In an effort to take the discussion forward with concrete design >>>>> options based on an end-to-end implementation, I have prototyped the >>>>> implementation (and added Spark support) in this PR >>>>> https://github.com/apache/iceberg/pull/9830. I hope it helps us reach >>>>> convergence faster. More details about some of the design options are >>>>> discussed in the description of the PR. >>>>> >>>>> Thanks, >>>>> Walaa. >>>>> >>>>> >>>>> On Wed, Feb 28, 2024 at 6:20 PM Ryan Blue <b...@tabular.io> wrote: >>>>> >>>>>> I mean separate table and view metadata that is somehow combined >>>>>> through a commit process. For instance, keeping a pointer to a table >>>>>> metadata file in a view metadata file or combining commits to reference >>>>>> both. I don't see the value in either option. >>>>>> >>>>>> On Wed, Feb 28, 2024 at 5:05 PM Jack Ye <yezhao...@gmail.com> wrote: >>>>>> >>>>>>> Thanks Ryan for the help to trace back to the root question! Just a >>>>>>> clarification question regarding your reply before I reply further: what >>>>>>> exactly does the option "a combination of the two (i.e. commits are >>>>>>> combined)" mean? How is that different from "a new metadata type"? >>>>>>> >>>>>>> -Jack >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Wed, Feb 28, 2024 at 2:10 PM Ryan Blue <b...@tabular.io> wrote: >>>>>>> >>>>>>>> I’m catching up on this conversation, so hopefully I can bring a >>>>>>>> fresh perspective. >>>>>>>> >>>>>>>> Jack already pointed out that we need to start from the basics and >>>>>>>> I agree with that. Let’s remove voting at this point. Right now is the >>>>>>>> time >>>>>>>> for discussing trade-offs, not lining up and taking sides. I realize >>>>>>>> that >>>>>>>> wasn’t the intent with adding a vote, but that’s almost always the >>>>>>>> result. >>>>>>>> It’s too easy to use it as a stand-in for consensus and move on >>>>>>>> prematurely. I get the impression from the swirl in Slack that >>>>>>>> discussion >>>>>>>> has moved ahead of agreement. >>>>>>>> >>>>>>>> We’re still at the most basic question: is a materialized view a >>>>>>>> view and a separate table, a combination of the two (i.e. commits are >>>>>>>> combined), or a new metadata type? >>>>>>>> >>>>>>>> For now, I’m ignoring whether the “separate table” is some kind of >>>>>>>> “system table” (meaning hidden?) or if it is exposed in the catalog. >>>>>>>> That’s >>>>>>>> a later choice (already pointed out) and, I suspect, it should be >>>>>>>> delegated >>>>>>>> to catalog implementations. >>>>>>>> >>>>>>>> To simplify this a little, I think that we can eliminate the option >>>>>>>> to combine table and view commits. I don’t think there is a reason to >>>>>>>> combine the two. If separate, a table would track the view version used >>>>>>>> along with freshness information for referenced tables. If the table is >>>>>>>> automatically skipped when the version no longer matches the view, >>>>>>>> then no >>>>>>>> action needs to happen when a view definition changes. Similarly, the >>>>>>>> table >>>>>>>> can be updated independently without needing to also swap view >>>>>>>> metadata. >>>>>>>> This also aligns with the idea from the original doc that there can be >>>>>>>> multiple materialization tables for a view. Each should operate >>>>>>>> independently unless I’m missing something >>>>>>>> >>>>>>>> I don’t think the last paragraph’s conclusion is contentious so >>>>>>>> I’ll move on, but please stop here and reply if you disagree! >>>>>>>> >>>>>>>> That leaves the main two options, a view and a separate table >>>>>>>> linked by metadata, or, combined materialized view metadata. >>>>>>>> >>>>>>>> As the doc notes, the separate view and table option is simpler >>>>>>>> because it reuses existing metadata definitions and falls back to >>>>>>>> simple >>>>>>>> views. That is a significantly smaller spec and small is very, very >>>>>>>> important when it comes to specs. I think that the argument for a new >>>>>>>> definition of a materialized view needs to overcome this disadvantage. >>>>>>>> >>>>>>>> The arguments that I see for a combined materialized view object >>>>>>>> are: >>>>>>>> >>>>>>>> - Regular views are separate, rather than being tables with SQL >>>>>>>> and no data so it would be inconsistent (“Iceberg view is just a >>>>>>>> table with >>>>>>>> no data but with representations defined. But we did not do that.”) >>>>>>>> - Materialized views are different objects in DDL >>>>>>>> - Tables may be a superset of functionality needed for >>>>>>>> materialized views >>>>>>>> - Tables are not typically exposed to end users — but this >>>>>>>> isn’t required by the separate view and table option >>>>>>>> >>>>>>>> Am I missing any arguments for combined metadata? >>>>>>>> >>>>>>>> Ryan >>>>>>>> -- >>>>>>>> Ryan Blue >>>>>>>> Tabular >>>>>>>> >>>>>>> >>>>>> >>>>>> -- >>>>>> Ryan Blue >>>>>> Tabular >>>>>> >>>>> >>> >>> -- >>> Ryan Blue >>> Tabular >>> >>>