omnata-plugin-runtime 0.11.0a312__py3-none-any.whl → 0.11.0a314__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -514,6 +514,29 @@ class SnowflakeViewParts(BaseModel):
514
514
  ..., description="The other streams that are joined to the main stream"
515
515
  )
516
516
 
517
+ def column_indirectly_references_other_streams(
518
+ self,
519
+ all_view_parts:List[SnowflakeViewPart],
520
+ stream_name:str,column_name:str) -> bool:
521
+
522
+ for part in all_view_parts:
523
+ if part.stream_name == stream_name:
524
+ for col in part.columns:
525
+ if col.original_name == column_name:
526
+ if col.referenced_columns:
527
+ for ref_stream, ref_cols in col.referenced_columns.items():
528
+ if ref_stream != stream_name:
529
+ return True
530
+ else:
531
+ # we have to call this recursively in case the referenced column also references other streams
532
+ result = any(
533
+ self.column_indirectly_references_other_streams(
534
+ all_view_parts, ref_stream, ref_col
535
+ ) for ref_col in ref_cols
536
+ )
537
+ return result
538
+ return False
539
+
517
540
  def view_body(self):
518
541
  """
519
542
  Creates a view definition from the parts.
@@ -529,31 +552,40 @@ class SnowflakeViewParts(BaseModel):
529
552
 
530
553
  # first, we need to collapse all referenced columns into a single map
531
554
  all_referenced_columns:Dict[str,List[str]] = {}
555
+
556
+ # if a column references other columns, but there are no dependencies outside of its own stream, we can include those columns in the initial CTE for that stream
557
+ # because they can be calculated directly without needing joins
558
+ columns_only_referencing_own_stream:Dict[str,List[str]] = {}
559
+
560
+
532
561
  for part in [self.main_part] + self.joined_parts:
533
- # if the main part references any columns in this part in its joins, we need to include those columns
562
+ # if the main part references any columns in this part in its joins, we need to include those columns because they are used in the join condition
534
563
  aliases_for_stream = [j.join_stream_alias for j in self.main_part.joins
535
564
  if j.join_stream_name == part.stream_name]
536
565
  columns_used_in_joins = [
537
566
  j.left_column for j in self.main_part.joins if j.left_alias in aliases_for_stream
538
567
  ]
539
- if part.stream_name not in all_referenced_columns:
540
- all_referenced_columns[part.stream_name] = []
541
- all_referenced_columns[part.stream_name] += columns_used_in_joins
568
+ all_referenced_columns.setdefault(part.stream_name, []).extend(columns_used_in_joins)
569
+ # now, for each column in the part, if it references columns in other streams, we need to include those columns
542
570
  for column in part.columns:
543
571
  if column.referenced_columns:
544
572
  for stream_name, referenced_columns in column.referenced_columns.items():
545
- if stream_name not in all_referenced_columns:
546
- all_referenced_columns[stream_name] = []
547
- all_referenced_columns[stream_name] += referenced_columns
573
+ all_referenced_columns.setdefault(stream_name, []).extend(referenced_columns)
574
+ # populate columns_only_referencing_own_stream by following the chain of references until we reach a column that references another stream or has no references
575
+ if self.column_indirectly_references_other_streams(
576
+ [self.main_part] + self.joined_parts, part.stream_name, column.original_name
577
+ ) == False:
578
+ columns_only_referencing_own_stream.setdefault(part.stream_name, []).append(column.original_name)
579
+ else:
580
+ # if the column has no references, it can be included in the initial CTE for its own stream
581
+ columns_only_referencing_own_stream.setdefault(part.stream_name, []).append(column.original_name)
582
+ # if this part has joins to other streams, we need to include the join columns
548
583
  for join in part.joins:
549
- if join.join_stream_name not in all_referenced_columns:
550
- all_referenced_columns[join.join_stream_name] = []
551
- all_referenced_columns[join.join_stream_name].append(join.join_stream_column)
552
- all_referenced_columns[part.stream_name].append(join.left_column)
553
-
584
+ all_referenced_columns.setdefault(join.join_stream_name, []).append(join.join_stream_column)
585
+ all_referenced_columns.setdefault(part.stream_name, []).append(join.left_column)
554
586
 
555
587
  ctes = [
556
- self.main_part.cte_text(original_name=True,include_extra_columns=all_referenced_columns.get(self.main_part.stream_name))
588
+ self.main_part.cte_text(original_name=True,include_extra_columns=columns_only_referencing_own_stream.get(self.main_part.stream_name))
557
589
  ] + [
558
590
  part.cte_text(original_name=True,include_only_columns=all_referenced_columns.get(part.stream_name))
559
591
  for part in joined_parts_deduped
@@ -563,9 +595,9 @@ class SnowflakeViewParts(BaseModel):
563
595
  final_cte = f""" OMNATA_FINAL_CTE as (
564
596
  select {', '.join(
565
597
  [
566
- f'"{self.main_part.stream_name}"."{c.original_name}"' for c in self.main_part.direct_columns()
598
+ f'"{self.main_part.stream_name}"."{c.original_name}"' for c in self.main_part.columns if not c.is_join_column or c.original_name in columns_only_referencing_own_stream.get(self.main_part.stream_name,[])
567
599
  ]+[
568
- c.definition(original_name=True) for c in self.main_part.join_columns()
600
+ c.definition(original_name=True) for c in self.main_part.columns if c.is_join_column and c.original_name not in columns_only_referencing_own_stream.get(self.main_part.stream_name,[])
569
601
  ])}
570
602
  from "{self.main_part.stream_name}" """
571
603
  if len(self.main_part.joins) > 0:
@@ -771,6 +803,19 @@ class SnowflakeViewParts(BaseModel):
771
803
 
772
804
  return cls(main_part=main_stream_view_part, joined_parts=joined_parts)
773
805
 
806
+
807
+ # Helper function to find a view part by stream name
808
+ def find_part(view_part: SnowflakeViewPart, joined_parts: List[SnowflakeViewPart], stream_name: str) -> Optional[SnowflakeViewPart]:
809
+ if stream_name == view_part.stream_name:
810
+ return view_part
811
+ for part in joined_parts:
812
+ if part.stream_name == stream_name:
813
+ return part
814
+ for join in view_part.joins:
815
+ if join.join_stream_alias == stream_name:
816
+ return view_part
817
+ return None
818
+
774
819
  def prune(view_part: SnowflakeViewPart, joined_parts: List[SnowflakeViewPart]) -> bool:
775
820
  """
776
821
  Prunes columns from view parts that reference fields that don't exist in the referenced streams.
@@ -783,12 +828,6 @@ def prune(view_part: SnowflakeViewPart, joined_parts: List[SnowflakeViewPart]) -
783
828
  Raises ValueError if a cyclic dependency is detected.
784
829
  """
785
830
  columns_removed = False
786
-
787
- # Helper function to find a view part by stream name
788
- def find_part(stream_name: str) -> Optional[SnowflakeViewPart]:
789
- if stream_name == view_part.stream_name:
790
- return view_part
791
- return next((p for p in joined_parts if p.stream_name == stream_name), None)
792
831
 
793
832
  # Helper function to check if a column should be kept or removed
794
833
  def should_keep_column(column: SnowflakeViewColumn, part: SnowflakeViewPart) -> bool:
@@ -803,7 +842,7 @@ def prune(view_part: SnowflakeViewPart, joined_parts: List[SnowflakeViewPart]) -
803
842
  # Check each referenced stream and its fields
804
843
  for ref_stream_name, ref_fields in column.referenced_columns.items():
805
844
  # Find the referenced part
806
- ref_part = find_part(ref_stream_name)
845
+ ref_part = find_part(view_part, joined_parts,ref_stream_name)
807
846
 
808
847
  # If referenced stream doesn't exist, remove the column
809
848
  if ref_part is None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: omnata-plugin-runtime
3
- Version: 0.11.0a312
3
+ Version: 0.11.0a314
4
4
  Summary: Classes and common runtime components for building and running Omnata Plugins
5
5
  Author: James Weakley
6
6
  Author-email: james.weakley@omnata.com
@@ -2,12 +2,12 @@ omnata_plugin_runtime/__init__.py,sha256=MS9d1whnfT_B3-ThqZ7l63QeC_8OEKTuaYV5wTw
2
2
  omnata_plugin_runtime/api.py,sha256=5gbjbnFy72Xjf0E3kbG23G0V2J3CorvD5kpBn_BkdlI,8084
3
3
  omnata_plugin_runtime/configuration.py,sha256=SffokJfgvy6V3kUsoEjXcK3GdNgHo6U3mgBEs0qBv4I,46972
4
4
  omnata_plugin_runtime/forms.py,sha256=Lrbr3otsFDrvHWJw7v-slsW4PvEHJ6BG1Yl8oaJfiDo,20529
5
- omnata_plugin_runtime/json_schema.py,sha256=CJaaN71fljgDWbDVNltHwLn-UKyJ_gy7S6YubW1uQok,50554
5
+ omnata_plugin_runtime/json_schema.py,sha256=w_4bnxZMzqRCzEUQi02ZlKOOyQ5CU71A_vTipw0XPBE,53191
6
6
  omnata_plugin_runtime/logging.py,sha256=WBuZt8lF9E5oFWM4KYQbE8dDJ_HctJ1pN3BHwU6rcd0,4461
7
7
  omnata_plugin_runtime/omnata_plugin.py,sha256=PV1BzsqI2yi3pd6DBSRc1s1QJ_My-b6pewrB7ad4sms,140256
8
8
  omnata_plugin_runtime/plugin_entrypoints.py,sha256=_1pDLov3iQorGmfcae8Sw2bVjxw1vYeowBaKKNzRclQ,32629
9
9
  omnata_plugin_runtime/rate_limiting.py,sha256=qpr5esU4Ks8hMzuMpSR3gLFdor2ZUXYWCjmsQH_K6lQ,25882
10
- omnata_plugin_runtime-0.11.0a312.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
11
- omnata_plugin_runtime-0.11.0a312.dist-info/METADATA,sha256=zsQbR1gu1SFvZTX6iK9zRXueSZXuemjUa1EoxJ7-zPQ,2211
12
- omnata_plugin_runtime-0.11.0a312.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
13
- omnata_plugin_runtime-0.11.0a312.dist-info/RECORD,,
10
+ omnata_plugin_runtime-0.11.0a314.dist-info/LICENSE,sha256=rGaMQG3R3F5-JGDp_-rlMKpDIkg5n0SI4kctTk8eZSI,56
11
+ omnata_plugin_runtime-0.11.0a314.dist-info/METADATA,sha256=yxlKyBrmjoHXXptlv4EeZG5_AhqN4tJZ3SuZjmJ6SFs,2211
12
+ omnata_plugin_runtime-0.11.0a314.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
13
+ omnata_plugin_runtime-0.11.0a314.dist-info/RECORD,,