gooddata-fdw 1.60.1.dev1__tar.gz → 1.60.1.dev2__tar.gz

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.
Files changed (58) hide show
  1. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/PKG-INFO +3 -3
  2. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/pyproject.toml +12 -3
  3. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/column_utils.py +2 -2
  4. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/environment.py +3 -3
  5. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/executor.py +5 -5
  6. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/fdw.py +3 -3
  7. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/import_workspace.py +4 -4
  8. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/naming.py +1 -3
  9. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/options.py +3 -3
  10. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/fixtures/execute_compute_table_all_columns.yaml +3 -3
  11. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/fixtures/execute_compute_table_metrics_only.yaml +3 -3
  12. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/fixtures/execute_compute_table_with_reduced_granularity.yaml +3 -3
  13. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/fixtures/execute_insight_all_columns.yaml +12 -7
  14. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/fixtures/execute_insight_some_columns.yaml +12 -7
  15. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/import_foreign_schema/fixtures/import_compute_without_restrictions.yaml +112 -62
  16. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/import_foreign_schema/fixtures/import_insights_without_restrictions.yaml +149 -89
  17. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tox.ini +1 -1
  18. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/.gitignore +0 -0
  19. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/.readthedocs.yaml +0 -0
  20. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/Dockerfile +0 -0
  21. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/LICENSE.txt +0 -0
  22. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/MANIFEST.in +0 -0
  23. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/Makefile +0 -0
  24. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/README.md +0 -0
  25. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/_static/empty_file +0 -0
  26. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/_templates/class-template.rst +0 -0
  27. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/_templates/module-template.rst +0 -0
  28. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/api.rst +0 -0
  29. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/conf.py +0 -0
  30. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/connecting_to_postgresql.rst +0 -0
  31. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/foreign_tables.rst +0 -0
  32. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/index.rst +0 -0
  33. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/installation.rst +0 -0
  34. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/docs/requirements.txt +0 -0
  35. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/rebuild.sh +0 -0
  36. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/sql/create_extensions.sql +0 -0
  37. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/sql/import_gooddata.sql +0 -0
  38. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/__init__.py +0 -0
  39. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/_version.py +0 -0
  40. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/column_validation.py +0 -0
  41. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/filter.py +0 -0
  42. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/pg_logging.py +0 -0
  43. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/src/gooddata_fdw/result_reader.py +0 -0
  44. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/__init__.py +0 -0
  45. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/conftest.py +0 -0
  46. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/__init__.py +0 -0
  47. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/test_execute_compute_table.py +0 -0
  48. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/execute/test_execute_insight.py +0 -0
  49. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/gd_test_config.yaml +0 -0
  50. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/import_foreign_schema/__init__.py +0 -0
  51. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/import_foreign_schema/test_import_compute.py +0 -0
  52. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/import_foreign_schema/test_import_insights.py +0 -0
  53. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/overview.md +0 -0
  54. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/unit_test/test_column_validation.py +0 -0
  55. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/unit_test/test_executor.py +0 -0
  56. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/unit_test/test_filter.py +0 -0
  57. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/unit_test/test_options.py +0 -0
  58. {gooddata_fdw-1.60.1.dev1 → gooddata_fdw-1.60.1.dev2}/tests/unit_test/test_result_reader.py +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gooddata-fdw
3
- Version: 1.60.1.dev1
3
+ Version: 1.60.1.dev2
4
4
  Summary: GoodData Cloud Foreign Data Wrapper For PostgreSQL
5
- Project-URL: Documentation, https://gooddata-fdw.readthedocs.io/en/v1.60.1.dev1
5
+ Project-URL: Documentation, https://gooddata-fdw.readthedocs.io/en/v1.60.1.dev2
6
6
  Project-URL: Source, https://github.com/gooddata/gooddata-python-sdk
7
7
  Author-email: GoodData <support@gooddata.com>
8
8
  License-Expression: MIT
@@ -20,7 +20,7 @@ Classifier: Topic :: Scientific/Engineering
20
20
  Classifier: Topic :: Software Development
21
21
  Classifier: Typing :: Typed
22
22
  Requires-Python: >=3.10
23
- Requires-Dist: gooddata-sdk~=1.60.1.dev1
23
+ Requires-Dist: gooddata-sdk~=1.60.1.dev2
24
24
  Description-Content-Type: text/markdown
25
25
 
26
26
  # GoodData Foreign Data Wrapper
@@ -1,7 +1,7 @@
1
1
  # (C) 2025 GoodData Corporation
2
2
  [project]
3
3
  name = "gooddata-fdw"
4
- version = "1.60.1.dev1"
4
+ version = "1.60.1.dev2"
5
5
  description = "GoodData Cloud Foreign Data Wrapper For PostgreSQL"
6
6
  readme = "README.md"
7
7
  license = "MIT"
@@ -26,7 +26,7 @@ keywords = [
26
26
  ]
27
27
  requires-python = ">=3.10"
28
28
  dependencies = [
29
- "gooddata-sdk~=1.60.1.dev1",
29
+ "gooddata-sdk~=1.60.1.dev2",
30
30
  # "multicorn>=1.4.0", # Uncommented as it was in original setup.py
31
31
  ]
32
32
  classifiers = [
@@ -44,7 +44,7 @@ classifiers = [
44
44
  ]
45
45
 
46
46
  [project.urls]
47
- Documentation = "https://gooddata-fdw.readthedocs.io/en/v1.60.1.dev1"
47
+ Documentation = "https://gooddata-fdw.readthedocs.io/en/v1.60.1.dev2"
48
48
  Source = "https://github.com/gooddata/gooddata-python-sdk"
49
49
 
50
50
  [dependency-groups]
@@ -65,6 +65,15 @@ allowed-unresolved-imports = ["multicorn"]
65
65
  [tool.hatch.build.targets.wheel]
66
66
  packages = ["src/gooddata_fdw"]
67
67
 
68
+ [tool.coverage.run]
69
+ source = ["gooddata_fdw"]
70
+
71
+ [tool.coverage.paths]
72
+ source = [
73
+ "src/gooddata_fdw",
74
+ "**/site-packages/gooddata_fdw",
75
+ ]
76
+
68
77
  [build-system]
69
78
  requires = ["hatchling"]
70
79
  build-backend = "hatchling.build"
@@ -1,7 +1,7 @@
1
1
  # (C) 2022 GoodData Corporation
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Optional, Union
4
+ from typing import Union
5
5
 
6
6
  import gooddata_sdk as sdk
7
7
  from gooddata_sdk import Attribute, CatalogAttribute, Metric
@@ -26,7 +26,7 @@ def table_col_as_computable(col: ColumnDefinition) -> Union[Attribute, Metric]:
26
26
  )
27
27
 
28
28
 
29
- def column_data_type_for(attribute: Optional[CatalogAttribute]) -> str:
29
+ def column_data_type_for(attribute: CatalogAttribute | None) -> str:
30
30
  """
31
31
  Determine what postgres type should be used for `attribute`.
32
32
 
@@ -14,7 +14,7 @@ as usual to prevent some wicked behavior on mis-configured PostgreSQL.
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
- from typing import Any, Optional, Union
17
+ from typing import Any, Union
18
18
 
19
19
  try:
20
20
  import multicorn
@@ -88,12 +88,12 @@ except ImportError as e:
88
88
  schema: str,
89
89
  srv_options: dict[str, str],
90
90
  options: dict[str, str],
91
- restriction_type: Optional[str],
91
+ restriction_type: str | None,
92
92
  restricts: list[str],
93
93
  ) -> list[TableDefinition]:
94
94
  return NotImplemented
95
95
 
96
- def execute(self, quals: list[Qual], columns: list[str], sortkeys: Optional[list[Any]] = None):
96
+ def execute(self, quals: list[Qual], columns: list[str], sortkeys: list[Any] | None = None):
97
97
  pass
98
98
 
99
99
  ForeignDataWrapper = ForeignDataWrapperStub
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from collections.abc import Generator
5
- from typing import Any, NamedTuple, Optional
5
+ from typing import Any, NamedTuple
6
6
 
7
7
  from gooddata_sdk import GoodDataSdk
8
8
 
@@ -37,7 +37,7 @@ class Executor:
37
37
  validator.validate(column_name, column_def)
38
38
 
39
39
  def execute(
40
- self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None
40
+ self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None
41
41
  ) -> Generator[dict[str, Any], None, None]:
42
42
  raise NotImplementedError()
43
43
 
@@ -59,7 +59,7 @@ class InsightExecutor(Executor):
59
59
  return inputs.table_options.insight is not None
60
60
 
61
61
  def execute(
62
- self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None
62
+ self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None
63
63
  ) -> Generator[dict[str, Any], None, None]:
64
64
  results_reader = InsightTableResultReader(self._table_columns, columns)
65
65
  insight = self._sdk.visualizations.get_visualization(self._workspace, self._insight)
@@ -81,7 +81,7 @@ class ComputeExecutor(Executor):
81
81
  return inputs.table_options.compute is not None
82
82
 
83
83
  def execute(
84
- self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None
84
+ self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None
85
85
  ) -> Generator[dict[str, Any], None, None]:
86
86
  col_val.validate_columns_in_table_def(self._table_columns, columns)
87
87
  items = [column_utils.table_col_as_computable(self._table_columns[col_name]) for col_name in columns]
@@ -105,7 +105,7 @@ class CustomExecutor(Executor):
105
105
  return True
106
106
 
107
107
  def execute(
108
- self, quals: list[Qual], columns: list[str], sort_keys: Optional[list[Any]] = None
108
+ self, quals: list[Qual], columns: list[str], sort_keys: list[Any] | None = None
109
109
  ) -> Generator[dict[str, Any], None, None]:
110
110
  items = [column_utils.table_col_as_computable(col) for col in self._table_columns.values()]
111
111
  # TODO: pushdown more filters that are included in quals
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import traceback
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
 
7
7
  from gooddata_sdk import GoodDataSdk
8
8
 
@@ -34,7 +34,7 @@ class GoodDataForeignDataWrapper(ForeignDataWrapper):
34
34
  self._executor = ExecutorFactory.create(InitData(gd_sdk, self._server_options, self._table_options, columns))
35
35
  self._executor.validate_columns_def()
36
36
 
37
- def execute(self, quals: list[Qual], columns: list[str], sortkeys: Optional[list[Any]] = None):
37
+ def execute(self, quals: list[Qual], columns: list[str], sortkeys: list[Any] | None = None):
38
38
  _log_debug(f"query in fdw with {self._server_options}; {self._table_options}; columns {columns}; quals={quals}")
39
39
  try:
40
40
  return self._executor.execute(quals, columns, sortkeys)
@@ -48,7 +48,7 @@ class GoodDataForeignDataWrapper(ForeignDataWrapper):
48
48
  schema: str,
49
49
  srv_options: dict[str, str],
50
50
  options: dict[str, str],
51
- restriction_type: Optional[str],
51
+ restriction_type: str | None,
52
52
  restricts: list[str],
53
53
  ) -> list[TableDefinition]:
54
54
  _log_info(
@@ -2,7 +2,7 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import re
5
- from typing import NamedTuple, Optional
5
+ from typing import NamedTuple
6
6
 
7
7
  from gooddata_sdk import (
8
8
  CatalogWorkspaceContent,
@@ -24,7 +24,7 @@ from gooddata_fdw.naming import (
24
24
  from gooddata_fdw.pg_logging import _log_debug, _log_info, _log_warn
25
25
 
26
26
 
27
- def _metric_format_to_precision(metric_format: Optional[str]) -> Optional[str]:
27
+ def _metric_format_to_precision(metric_format: str | None) -> str | None:
28
28
  if metric_format:
29
29
  re_decimal_places = re.compile(r"^[^.]+\.([#0]+)")
30
30
  match = re_decimal_places.search(metric_format)
@@ -39,7 +39,7 @@ class ImporterInitData(NamedTuple):
39
39
  workspace: str
40
40
  server_options: options.ServerOptions
41
41
  import_options: options.ImportSchemaOptions
42
- restriction_type: Optional[str]
42
+ restriction_type: str | None
43
43
  restricts: list[str]
44
44
 
45
45
 
@@ -165,7 +165,7 @@ class InsightsWorkspaceImporter(WorkspaceImporter):
165
165
 
166
166
  # InsightMetric do not contain format in case of stored metrics
167
167
  @staticmethod
168
- def _get_insight_metric_format(metric: VisualizationMetric, catalog: CatalogWorkspaceContent) -> Optional[str]:
168
+ def _get_insight_metric_format(metric: VisualizationMetric, catalog: CatalogWorkspaceContent) -> str | None:
169
169
  if metric.format:
170
170
  return metric.format
171
171
  elif metric.item_id:
@@ -1,12 +1,10 @@
1
1
  # (C) 2021 GoodData Corporation
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Optional
5
-
6
4
  import gooddata_sdk as sdk
7
5
 
8
6
 
9
- def _sanitize_str_for_postgres(string: str, used_names: Optional[dict[str, bool]] = None) -> str:
7
+ def _sanitize_str_for_postgres(string: str, used_names: dict[str, bool] | None = None) -> str:
10
8
  # replace non-alpha-num stuff with underscores
11
9
  with_underscores = "".join(char if char.isalnum() else "_" for char in string.lower())
12
10
 
@@ -1,11 +1,11 @@
1
1
  # (C) 2022 GoodData Corporation
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Any, Optional, Union
4
+ from typing import Any, Union
5
5
 
6
6
 
7
7
  class BaseOptions:
8
- def __init__(self, validate: bool = True, skip_attributes: Optional[list[str]] = None) -> None:
8
+ def __init__(self, validate: bool = True, skip_attributes: list[str] | None = None) -> None:
9
9
  if skip_attributes is None:
10
10
  self._skip_attributes = []
11
11
  else:
@@ -124,6 +124,6 @@ class ImportSchemaOptions(BaseOptions):
124
124
  def numeric_max_size(self) -> str:
125
125
  return self._options.get("numeric_max_size", self.METRIC_DIGITS_BEFORE_DEC_POINT_DEFAULT)
126
126
 
127
- def metric_data_type(self, precision: Optional[str] = None) -> str:
127
+ def metric_data_type(self, precision: str | None = None) -> str:
128
128
  digits_after = precision if precision else self.METRIC_DIGITS_AFTER_DEC_POINT_DEFAULT
129
129
  return f"DECIMAL({self.numeric_max_size}, {digits_after})"
@@ -103,7 +103,7 @@ interactions:
103
103
  X-Content-Type-Options:
104
104
  - nosniff
105
105
  X-Gdc-Cancel-Token:
106
- - 15359989-8ad2-4797-872d-0c75e9d2fc54
106
+ - 75ebf79c-8b57-413e-8905-8f87c275d7c7
107
107
  X-GDC-TRACE-ID: *id001
108
108
  X-Xss-Protection:
109
109
  - '0'
@@ -155,10 +155,10 @@ interactions:
155
155
  name: Revenue
156
156
  localIdentifier: dim_1
157
157
  links:
158
- executionResult: e318af2d275ae11561a9ab4c66bac635449f57cf:9b16b2d4f10df23824722646ce1af02eb946c80c6d65fb454e6082eba84bcf47
158
+ executionResult: d60b337013fca31600abb3d636b0552824481d3d:3b1a7fd80969c75386d4191687e7aac6411e48e74da9eaa0c44699c8b65e5771
159
159
  - request:
160
160
  method: GET
161
- uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/e318af2d275ae11561a9ab4c66bac635449f57cf%3A9b16b2d4f10df23824722646ce1af02eb946c80c6d65fb454e6082eba84bcf47?offset=0%2C0&limit=512%2C256
161
+ uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/d60b337013fca31600abb3d636b0552824481d3d%3A3b1a7fd80969c75386d4191687e7aac6411e48e74da9eaa0c44699c8b65e5771?offset=0%2C0&limit=512%2C256
162
162
  body: null
163
163
  headers:
164
164
  Accept:
@@ -89,7 +89,7 @@ interactions:
89
89
  X-Content-Type-Options:
90
90
  - nosniff
91
91
  X-Gdc-Cancel-Token:
92
- - f191b3ad-a319-479c-8e29-02cca428b1b5
92
+ - 89bdbce1-989f-4d02-a05b-c4651acb16f1
93
93
  X-GDC-TRACE-ID: *id001
94
94
  X-Xss-Protection:
95
95
  - '0'
@@ -109,10 +109,10 @@ interactions:
109
109
  name: Revenue
110
110
  localIdentifier: dim_0
111
111
  links:
112
- executionResult: d9d11f7d9e8253a0c876b653d8cdd13837d4d7e3:f88453cd7ca8a9b78b512af78d0d58514f1c4d378dbb3ec42641642e1d30b7d7
112
+ executionResult: 0f6e8c819d2076d126957770f4de7c7cfdbe94f2:b9fb86afba4a0826554e9283de0216a56182a625b327e2f2086007c84261356b
113
113
  - request:
114
114
  method: GET
115
- uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/d9d11f7d9e8253a0c876b653d8cdd13837d4d7e3%3Af88453cd7ca8a9b78b512af78d0d58514f1c4d378dbb3ec42641642e1d30b7d7?offset=0&limit=256
115
+ uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/0f6e8c819d2076d126957770f4de7c7cfdbe94f2%3Ab9fb86afba4a0826554e9283de0216a56182a625b327e2f2086007c84261356b?offset=0&limit=256
116
116
  body: null
117
117
  headers:
118
118
  Accept:
@@ -78,7 +78,7 @@ interactions:
78
78
  X-Content-Type-Options:
79
79
  - nosniff
80
80
  X-Gdc-Cancel-Token:
81
- - 5bc1e217-8ae2-447d-bd49-d272c789a346
81
+ - 3faa3be7-abe9-4ea1-970b-9e4ea6761c55
82
82
  X-GDC-TRACE-ID: *id001
83
83
  X-Xss-Protection:
84
84
  - '0'
@@ -111,10 +111,10 @@ interactions:
111
111
  name: Revenue
112
112
  localIdentifier: dim_1
113
113
  links:
114
- executionResult: 17828286356601efacb6b95fa54c984dc65d83ed:1a99055686e8543963519414ed3103816d7b01d6916f6883767a9642304fcaa7
114
+ executionResult: 8fc634415680e148db8133f5bcd7246f5e0a3c66:660c43f4d90efd070912c98150124c6fdf8549fed14b6eb512a830ff17d7f8b3
115
115
  - request:
116
116
  method: GET
117
- uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/17828286356601efacb6b95fa54c984dc65d83ed%3A1a99055686e8543963519414ed3103816d7b01d6916f6883767a9642304fcaa7?offset=0%2C0&limit=512%2C256
117
+ uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/8fc634415680e148db8133f5bcd7246f5e0a3c66%3A660c43f4d90efd070912c98150124c6fdf8549fed14b6eb512a830ff17d7f8b3?offset=0%2C0&limit=512%2C256
118
118
  body: null
119
119
  headers:
120
120
  Accept:
@@ -22,7 +22,7 @@ interactions:
22
22
  Cache-Control:
23
23
  - no-cache, no-store, max-age=0, must-revalidate
24
24
  Content-Length:
25
- - '5006'
25
+ - '5096'
26
26
  Content-Type:
27
27
  - application/json
28
28
  DATE: &id001
@@ -141,7 +141,7 @@ interactions:
141
141
  direction: asc
142
142
  version: '2'
143
143
  visualizationUrl: local:table
144
- createdAt: 2026-02-16 14:48
144
+ createdAt: 2025-08-07 11:45
145
145
  id: revenue_and_quantity_by_product_and_category
146
146
  meta:
147
147
  origin:
@@ -181,6 +181,7 @@ interactions:
181
181
  - Order lines
182
182
  sourceColumn: quantity
183
183
  sourceColumnDataType: NUMERIC
184
+ isNullable: true
184
185
  id: quantity
185
186
  links:
186
187
  self: http://localhost:3000/api/v1/entities/workspaces/demo/facts/quantity
@@ -192,7 +193,7 @@ interactions:
192
193
  format: $#,##0
193
194
  maql: SELECT {metric/order_amount} WHERE NOT ({label/order_status}
194
195
  IN ("Returned", "Canceled"))
195
- createdAt: 2026-02-16 14:48
196
+ createdAt: 2025-08-07 11:45
196
197
  id: revenue
197
198
  links:
198
199
  self: http://localhost:3000/api/v1/entities/workspaces/demo/metrics/revenue
@@ -204,6 +205,7 @@ interactions:
204
205
  - Order lines
205
206
  sourceColumn: price
206
207
  sourceColumnDataType: NUMERIC
208
+ isNullable: true
207
209
  id: price
208
210
  links:
209
211
  self: http://localhost:3000/api/v1/entities/workspaces/demo/facts/price
@@ -217,6 +219,7 @@ interactions:
217
219
  sourceColumn: product_name
218
220
  sourceColumnDataType: STRING
219
221
  valueType: TEXT
222
+ isNullable: true
220
223
  id: product_name
221
224
  links:
222
225
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/product_name
@@ -235,6 +238,7 @@ interactions:
235
238
  sourceColumn: customer_name
236
239
  sourceColumnDataType: STRING
237
240
  valueType: TEXT
241
+ isNullable: true
238
242
  id: customer_name
239
243
  links:
240
244
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/customer_name
@@ -245,7 +249,7 @@ interactions:
245
249
  format: '#,##0.0%'
246
250
  maql: SELECT {metric/revenue} / (SELECT {metric/revenue} BY {attribute/products.category},
247
251
  ALL OTHER)
248
- createdAt: 2026-02-16 14:48
252
+ createdAt: 2025-08-07 11:45
249
253
  id: percent_revenue_in_category
250
254
  links:
251
255
  self: http://localhost:3000/api/v1/entities/workspaces/demo/metrics/percent_revenue_in_category
@@ -259,6 +263,7 @@ interactions:
259
263
  sourceColumn: category
260
264
  sourceColumnDataType: STRING
261
265
  valueType: TEXT
266
+ isNullable: true
262
267
  id: products.category
263
268
  links:
264
269
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/products.category
@@ -370,7 +375,7 @@ interactions:
370
375
  X-Content-Type-Options:
371
376
  - nosniff
372
377
  X-Gdc-Cancel-Token:
373
- - b8262e8d-176e-48a3-8bd5-70dd69162f12
378
+ - 9773d1f6-996c-41d2-bf00-605307ab0284
374
379
  X-GDC-TRACE-ID: *id001
375
380
  X-Xss-Protection:
376
381
  - '0'
@@ -422,10 +427,10 @@ interactions:
422
427
  name: Revenue
423
428
  localIdentifier: dim_1
424
429
  links:
425
- executionResult: 45de8ca1701935fef0b7b962236aa2b30a2f29a7:edd8e464e013b84e886575575e2cefc8c34af5a2aa2c0d98222150b19405fcfb
430
+ executionResult: b83f490bb62cdbf7c4775031d6be518ec4b6c922:87b0990eecc60e2913654ddb0e0bab5a51cfc352ae558cbc0e55a0f98fdb2e37
426
431
  - request:
427
432
  method: GET
428
- uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/45de8ca1701935fef0b7b962236aa2b30a2f29a7%3Aedd8e464e013b84e886575575e2cefc8c34af5a2aa2c0d98222150b19405fcfb?offset=0%2C0&limit=512%2C256
433
+ uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/b83f490bb62cdbf7c4775031d6be518ec4b6c922%3A87b0990eecc60e2913654ddb0e0bab5a51cfc352ae558cbc0e55a0f98fdb2e37?offset=0%2C0&limit=512%2C256
429
434
  body: null
430
435
  headers:
431
436
  Accept:
@@ -22,7 +22,7 @@ interactions:
22
22
  Cache-Control:
23
23
  - no-cache, no-store, max-age=0, must-revalidate
24
24
  Content-Length:
25
- - '5006'
25
+ - '5096'
26
26
  Content-Type:
27
27
  - application/json
28
28
  DATE: &id001
@@ -141,7 +141,7 @@ interactions:
141
141
  direction: asc
142
142
  version: '2'
143
143
  visualizationUrl: local:table
144
- createdAt: 2026-02-16 14:48
144
+ createdAt: 2025-08-07 11:45
145
145
  id: revenue_and_quantity_by_product_and_category
146
146
  meta:
147
147
  origin:
@@ -181,6 +181,7 @@ interactions:
181
181
  - Order lines
182
182
  sourceColumn: quantity
183
183
  sourceColumnDataType: NUMERIC
184
+ isNullable: true
184
185
  id: quantity
185
186
  links:
186
187
  self: http://localhost:3000/api/v1/entities/workspaces/demo/facts/quantity
@@ -192,7 +193,7 @@ interactions:
192
193
  format: $#,##0
193
194
  maql: SELECT {metric/order_amount} WHERE NOT ({label/order_status}
194
195
  IN ("Returned", "Canceled"))
195
- createdAt: 2026-02-16 14:48
196
+ createdAt: 2025-08-07 11:45
196
197
  id: revenue
197
198
  links:
198
199
  self: http://localhost:3000/api/v1/entities/workspaces/demo/metrics/revenue
@@ -204,6 +205,7 @@ interactions:
204
205
  - Order lines
205
206
  sourceColumn: price
206
207
  sourceColumnDataType: NUMERIC
208
+ isNullable: true
207
209
  id: price
208
210
  links:
209
211
  self: http://localhost:3000/api/v1/entities/workspaces/demo/facts/price
@@ -217,6 +219,7 @@ interactions:
217
219
  sourceColumn: product_name
218
220
  sourceColumnDataType: STRING
219
221
  valueType: TEXT
222
+ isNullable: true
220
223
  id: product_name
221
224
  links:
222
225
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/product_name
@@ -235,6 +238,7 @@ interactions:
235
238
  sourceColumn: customer_name
236
239
  sourceColumnDataType: STRING
237
240
  valueType: TEXT
241
+ isNullable: true
238
242
  id: customer_name
239
243
  links:
240
244
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/customer_name
@@ -245,7 +249,7 @@ interactions:
245
249
  format: '#,##0.0%'
246
250
  maql: SELECT {metric/revenue} / (SELECT {metric/revenue} BY {attribute/products.category},
247
251
  ALL OTHER)
248
- createdAt: 2026-02-16 14:48
252
+ createdAt: 2025-08-07 11:45
249
253
  id: percent_revenue_in_category
250
254
  links:
251
255
  self: http://localhost:3000/api/v1/entities/workspaces/demo/metrics/percent_revenue_in_category
@@ -259,6 +263,7 @@ interactions:
259
263
  sourceColumn: category
260
264
  sourceColumnDataType: STRING
261
265
  valueType: TEXT
266
+ isNullable: true
262
267
  id: products.category
263
268
  links:
264
269
  self: http://localhost:3000/api/v1/entities/workspaces/demo/labels/products.category
@@ -370,7 +375,7 @@ interactions:
370
375
  X-Content-Type-Options:
371
376
  - nosniff
372
377
  X-Gdc-Cancel-Token:
373
- - 90bb0a95-a1ef-497f-97c7-933c6eb74b74
378
+ - 66d702d3-4533-4a10-91db-ea0e4c97625c
374
379
  X-GDC-TRACE-ID: *id001
375
380
  X-Xss-Protection:
376
381
  - '0'
@@ -422,10 +427,10 @@ interactions:
422
427
  name: Revenue
423
428
  localIdentifier: dim_1
424
429
  links:
425
- executionResult: 45de8ca1701935fef0b7b962236aa2b30a2f29a7:edd8e464e013b84e886575575e2cefc8c34af5a2aa2c0d98222150b19405fcfb
430
+ executionResult: b83f490bb62cdbf7c4775031d6be518ec4b6c922:87b0990eecc60e2913654ddb0e0bab5a51cfc352ae558cbc0e55a0f98fdb2e37
426
431
  - request:
427
432
  method: GET
428
- uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/45de8ca1701935fef0b7b962236aa2b30a2f29a7%3Aedd8e464e013b84e886575575e2cefc8c34af5a2aa2c0d98222150b19405fcfb?offset=0%2C0&limit=512%2C256
433
+ uri: http://localhost:3000/api/v1/actions/workspaces/demo/execution/afm/execute/result/b83f490bb62cdbf7c4775031d6be518ec4b6c922%3A87b0990eecc60e2913654ddb0e0bab5a51cfc352ae558cbc0e55a0f98fdb2e37?offset=0%2C0&limit=512%2C256
429
434
  body: null
430
435
  headers:
431
436
  Accept: