recce-nightly 1.4.0.20250519__tar.gz → 1.4.0.20250520__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.

Potentially problematic release.


This version of recce-nightly might be problematic. Click here for more details.

Files changed (151) hide show
  1. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/PKG-INFO +1 -1
  2. recce_nightly-1.4.0.20250520/recce/VERSION +1 -0
  3. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/adapter/dbt_adapter/__init__.py +2 -1
  4. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/404.html +1 -1
  5. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/index.html +1 -1
  6. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/index.txt +1 -1
  7. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/breaking.py +2 -2
  8. recce_nightly-1.4.0.20250520/recce/util/cll.py +336 -0
  9. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/PKG-INFO +1 -1
  10. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/SOURCES.txt +2 -2
  11. recce_nightly-1.4.0.20250519/recce/VERSION +0 -1
  12. recce_nightly-1.4.0.20250519/recce/util/cll.py +0 -304
  13. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/LICENSE +0 -0
  14. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/README.md +0 -0
  15. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/pyproject.toml +0 -0
  16. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/__init__.py +0 -0
  17. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/adapter/__init__.py +0 -0
  18. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/adapter/base.py +0 -0
  19. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/adapter/dbt_adapter/dbt_version.py +0 -0
  20. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/adapter/sqlmesh_adapter.py +0 -0
  21. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/apis/__init__.py +0 -0
  22. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/apis/check_api.py +0 -0
  23. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/apis/check_func.py +0 -0
  24. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/apis/run_api.py +0 -0
  25. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/apis/run_func.py +0 -0
  26. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/artifact.py +0 -0
  27. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/cli.py +0 -0
  28. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/config.py +0 -0
  29. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/core.py +0 -0
  30. {recce_nightly-1.4.0.20250519/recce/data/_next/static/eIqnO-Nu8atPURSm-S7vW → recce_nightly-1.4.0.20250520/recce/data/_next/static/POqJHyxRZAKc5Vb7Bi6Gz}/_buildManifest.js +0 -0
  31. {recce_nightly-1.4.0.20250519/recce/data/_next/static/eIqnO-Nu8atPURSm-S7vW → recce_nightly-1.4.0.20250520/recce/data/_next/static/POqJHyxRZAKc5Vb7Bi6Gz}/_ssgManifest.js +0 -0
  32. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js +0 -0
  33. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js +0 -0
  34. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js +0 -0
  35. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/3998a672-eaad84bdd88cc73e.js +0 -0
  36. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/3a92ee20-3b5d922d4157af5e.js +0 -0
  37. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/450c323b-1bb5db526e54435a.js +0 -0
  38. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js +0 -0
  39. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js +0 -0
  40. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/6ef81909-694dc38134099299.js +0 -0
  41. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/700-3b65fc3666820d00.js +0 -0
  42. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/778-aef312bffb4c0312.js +0 -0
  43. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js +0 -0
  44. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/7f27ae6c-413f6b869a04183a.js +0 -0
  45. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js +0 -0
  46. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/9746af58-d74bef4d03eea6ab.js +0 -0
  47. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/a30376cd-7d806e1602f2dc3a.js +0 -0
  48. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/app/_not-found/page-8a886fa0855c3105.js +0 -0
  49. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js +0 -0
  50. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/app/page-7086764277331fcb.js +0 -0
  51. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js +0 -0
  52. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/c132bf7d-8102037f9ccf372a.js +0 -0
  53. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js +0 -0
  54. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/cd9f8d63-e020f408095ed77c.js +0 -0
  55. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/ce84277d-f42c2c58049cea2d.js +0 -0
  56. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/e24bf851-0f8cbc99656833e7.js +0 -0
  57. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/fee69bc6-f17d36c080742e74.js +0 -0
  58. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/framework-ded83d71b51ce901.js +0 -0
  59. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/main-a0859f1f36d0aa6c.js +0 -0
  60. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/main-app-0225a2255968e566.js +0 -0
  61. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js +0 -0
  62. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js +0 -0
  63. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -0
  64. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js +0 -0
  65. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/css/88b8abc134cfd59a.css +0 -0
  66. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/css/c9ecb46a4b21c126.css +0 -0
  67. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2 +0 -0
  68. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff +0 -0
  69. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff +0 -0
  70. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2 +0 -0
  71. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2 +0 -0
  72. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-latin-800-normal.97e20d5e.woff +0 -0
  73. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2 +0 -0
  74. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff +0 -0
  75. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff +0 -0
  76. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2 +0 -0
  77. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/favicon.ico +0 -0
  78. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/imgs/feedback/thumbs-down.png +0 -0
  79. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/imgs/feedback/thumbs-up.png +0 -0
  80. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/data/logo/recce-logo-white.png +0 -0
  81. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/diff.py +0 -0
  82. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/event/CONFIG +0 -0
  83. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/event/SENTRY_DNS +0 -0
  84. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/event/__init__.py +0 -0
  85. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/event/collector.py +0 -0
  86. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/event/track.py +0 -0
  87. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/exceptions.py +0 -0
  88. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/git.py +0 -0
  89. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/github.py +0 -0
  90. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/models/__init__.py +0 -0
  91. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/models/check.py +0 -0
  92. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/models/run.py +0 -0
  93. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/models/types.py +0 -0
  94. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/pull_request.py +0 -0
  95. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/run.py +0 -0
  96. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/server.py +0 -0
  97. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/state.py +0 -0
  98. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/summary.py +0 -0
  99. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/__init__.py +0 -0
  100. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/core.py +0 -0
  101. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/dataframe.py +0 -0
  102. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/histogram.py +0 -0
  103. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/lineage.py +0 -0
  104. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/profile.py +0 -0
  105. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/query.py +0 -0
  106. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/rowcount.py +0 -0
  107. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/schema.py +0 -0
  108. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/top_k.py +0 -0
  109. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/tasks/valuediff.py +0 -0
  110. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/__init__.py +0 -0
  111. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/cache.py +0 -0
  112. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/io.py +0 -0
  113. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/lineage.py +0 -0
  114. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/logger.py +0 -0
  115. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/pydantic_model.py +0 -0
  116. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/recce_cloud.py +0 -0
  117. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/util/singleton.py +0 -0
  118. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce/yaml/__init__.py +0 -0
  119. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/dependency_links.txt +0 -0
  120. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/entry_points.txt +0 -0
  121. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/requires.txt +0 -0
  122. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/recce_nightly.egg-info/top_level.txt +0 -0
  123. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/setup.cfg +0 -0
  124. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/setup.py +0 -0
  125. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/__init__.py +0 -0
  126. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/__init__.py +0 -0
  127. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/__init__.py +0 -0
  128. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/conftest.py +0 -0
  129. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/dbt_test_helper.py +0 -0
  130. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -0
  131. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/test_dbt_cll.py +0 -0
  132. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/adapter/dbt_adapter/test_selector.py +0 -0
  133. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/__init__.py +0 -0
  134. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/conftest.py +0 -0
  135. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_histogram.py +0 -0
  136. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_lineage.py +0 -0
  137. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_preset_checks.py +0 -0
  138. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_profile.py +0 -0
  139. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_query.py +0 -0
  140. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_row_count.py +0 -0
  141. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_schema.py +0 -0
  142. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_top_k.py +0 -0
  143. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/tasks/test_valuediff.py +0 -0
  144. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_cli.py +0 -0
  145. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_config.py +0 -0
  146. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_core.py +0 -0
  147. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_dbt.py +0 -0
  148. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_pull_request.py +0 -0
  149. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_server.py +0 -0
  150. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_state.py +0 -0
  151. {recce_nightly-1.4.0.20250519 → recce_nightly-1.4.0.20250520}/tests/test_summary.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recce-nightly
3
- Version: 1.4.0.20250519
3
+ Version: 1.4.0.20250520
4
4
  Summary: Environment diff tool for dbt
5
5
  Home-page: https://github.com/InfuseAI/recce
6
6
  Author: InfuseAI Dev Team
@@ -0,0 +1 @@
1
+ 1.4.0.20250520
@@ -24,7 +24,8 @@ from typing import (
24
24
 
25
25
  from recce.event import log_performance
26
26
  from recce.exceptions import RecceException
27
- from recce.util.cll import CLLPerformanceTracking, cll
27
+ from recce.util.cll import CLLPerformanceTracking
28
+ from recce.util.cll import cll_old as cll
28
29
  from recce.util.lineage import find_downstream, find_upstream
29
30
 
30
31
  from ...tasks.profile import ProfileTask
@@ -1 +1 @@
1
- <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/88b8abc134cfd59a.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b787cb1a4f2293de.js"/><script src="/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js" async=""></script><script src="/_next/static/chunks/700-3b65fc3666820d00.js" async=""></script><script src="/_next/static/chunks/main-app-0225a2255968e566.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-b787cb1a4f2293de.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/88b8abc134cfd59a.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[37194,[],\"\"]\n4:I[79137,[],\"\"]\n5:I[63846,[],\"\"]\nb:I[67160,[],\"\"]\n6:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n7:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n8:{\"display\":\"inline-block\"}\n9:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"eIqnO-Nu8atPURSm-S7vW\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/88b8abc134cfd59a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$6\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$7\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$9\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n3:null\n"])</script></body></html>
1
+ <!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/88b8abc134cfd59a.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-b787cb1a4f2293de.js"/><script src="/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js" async=""></script><script src="/_next/static/chunks/700-3b65fc3666820d00.js" async=""></script><script src="/_next/static/chunks/main-app-0225a2255968e566.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>recce</title><meta name="description" content="Recce: Data validation toolkit for comprehensive PR review"/><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><script src="/_next/static/chunks/webpack-b787cb1a4f2293de.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/88b8abc134cfd59a.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"2:I[37194,[],\"\"]\n4:I[79137,[],\"\"]\n5:I[63846,[],\"\"]\nb:I[67160,[],\"\"]\n6:{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"}\n7:{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"}\n8:{\"display\":\"inline-block\"}\n9:{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0}\nc:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L2\",null,{\"buildId\":\"POqJHyxRZAKc5Vb7Bi6Gz\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"_not-found\"],\"initialTree\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{},[[\"$L3\",[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null],null],null]},[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\",\"/_not-found\",\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"notFoundStyles\":\"$undefined\"}]],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/88b8abc134cfd59a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":\"$6\",\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":\"$7\",\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":\"$8\",\"children\":[\"$\",\"h2\",null,{\"style\":\"$9\",\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],\"$La\"],\"globalErrorComponent\":\"$b\",\"missingSlots\":\"$Wc\"}]\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}]]\n3:null\n"])</script></body></html>
@@ -24,4 +24,4 @@
24
24
  transparent 0%,
25
25
  #3182ce 50%,
26
26
  transparent 100%
27
- );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-b787cb1a4f2293de.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/88b8abc134cfd59a.css\",\"style\"]\n2:HL[\"/_next/static/css/c9ecb46a4b21c126.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[37194,[],\"\"]\n5:I[86822,[],\"ClientPageRoot\"]\n6:I[1996,[\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"648\",\"static/chunks/ce84277d-f42c2c58049cea2d.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-7d806e1602f2dc3a.js\",\"995\",\"static/chunks/fee69bc6-f17d36c080742e74.js\",\"739\",\"static/chunks/7a8a3e83-d7fa409d97b38b2b.js\",\"283\",\"static/chunks/450c323b-1bb5db526e54435a.js\",\"303\",\"static/chunks/36e1c10d-bb0210cbd6573a8d.js\",\"22\",\"static/chunks/29e3cc0d-8c150e37dff9631b.js\",\"25\",\"static/chunks/b63b1b3f-7395c74e11a14e95.js\",\"355\",\"static/chunks/7f27ae6c-413f6b869a04183a.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"599\",\"static/chunks/c132bf7d-8102037f9ccf372a.js\",\"971\",\"static/chunks/cd9f8d63-e020f408095ed77c.js\",\"778\",\"static/chunks/778-aef312bffb4c0312.js\",\"931\",\"static/chunks/app/page-7086764277331fcb.js\"],\"default\",1]\n7:I[79137,[],\"\"]\n8:I[63846,[],\"\"]\na:I[67160,[],\"\"]\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"eIqnO-Nu8atPURSm-S7vW\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L4\",[\"$\",\"$L5\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$6\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c9ecb46a4b21c126.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/88b8abc134cfd59a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L9\"],\"globalErrorComponent\":\"$a\",\"missingSlots\":\"$Wb\"}]\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n4:null\n"])</script></body></html>
27
+ );position:absolute;will-change:left;min-width:50%;-webkit-animation:animation-11lmxjq 1s ease infinite normal none running;animation:animation-11lmxjq 1s ease infinite normal none running;}@-webkit-keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}@keyframes animation-11lmxjq{0%{left:-40%;}100%{left:100%;}}</style><div style="width:0%" data-indeterminate="" aria-valuemax="100" aria-valuemin="0" role="progressbar" class="css-h5ends"></div></div></div><div class="css-0"></div></div></div></div><span></span><span id="__chakra_env" hidden=""></span><script src="/_next/static/chunks/webpack-b787cb1a4f2293de.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/css/88b8abc134cfd59a.css\",\"style\"]\n2:HL[\"/_next/static/css/c9ecb46a4b21c126.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[37194,[],\"\"]\n5:I[86822,[],\"ClientPageRoot\"]\n6:I[1996,[\"266\",\"static/chunks/e24bf851-0f8cbc99656833e7.js\",\"517\",\"static/chunks/c1ceaa8b-a1e442154d23515e.js\",\"376\",\"static/chunks/3a92ee20-3b5d922d4157af5e.js\",\"455\",\"static/chunks/6ef81909-694dc38134099299.js\",\"678\",\"static/chunks/3998a672-eaad84bdd88cc73e.js\",\"509\",\"static/chunks/9746af58-d74bef4d03eea6ab.js\",\"648\",\"static/chunks/ce84277d-f42c2c58049cea2d.js\",\"989\",\"static/chunks/47d8844f-79a1b53c66a7d7ec.js\",\"147\",\"static/chunks/a30376cd-7d806e1602f2dc3a.js\",\"995\",\"static/chunks/fee69bc6-f17d36c080742e74.js\",\"739\",\"static/chunks/7a8a3e83-d7fa409d97b38b2b.js\",\"283\",\"static/chunks/450c323b-1bb5db526e54435a.js\",\"303\",\"static/chunks/36e1c10d-bb0210cbd6573a8d.js\",\"22\",\"static/chunks/29e3cc0d-8c150e37dff9631b.js\",\"25\",\"static/chunks/b63b1b3f-7395c74e11a14e95.js\",\"355\",\"static/chunks/7f27ae6c-413f6b869a04183a.js\",\"495\",\"static/chunks/6dc81886-c94b9b91bc2c3caf.js\",\"599\",\"static/chunks/c132bf7d-8102037f9ccf372a.js\",\"971\",\"static/chunks/cd9f8d63-e020f408095ed77c.js\",\"778\",\"static/chunks/778-aef312bffb4c0312.js\",\"931\",\"static/chunks/app/page-7086764277331fcb.js\"],\"default\",1]\n7:I[79137,[],\"\"]\n8:I[63846,[],\"\"]\na:I[67160,[],\"\"]\nb:[]\n"])</script><script>self.__next_f.push([1,"0:[\"$\",\"$L3\",null,{\"buildId\":\"POqJHyxRZAKc5Vb7Bi6Gz\",\"assetPrefix\":\"\",\"urlParts\":[\"\",\"\"],\"initialTree\":[\"\",{\"children\":[\"__PAGE__\",{}]},\"$undefined\",\"$undefined\",true],\"initialSeedData\":[\"\",{\"children\":[\"__PAGE__\",{},[[\"$L4\",[\"$\",\"$L5\",null,{\"props\":{\"params\":{},\"searchParams\":{}},\"Component\":\"$6\"}],[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c9ecb46a4b21c126.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]]],null],null]},[[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/88b8abc134cfd59a.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"children\":[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L7\",null,{\"parallelRouterKey\":\"children\",\"segmentPath\":[\"children\"],\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L8\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":\"404\"}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],\"notFoundStyles\":[]}]}]}]],null],null],\"couldBeIntercepted\":false,\"initialHead\":[null,\"$L9\"],\"globalErrorComponent\":\"$a\",\"missingSlots\":\"$Wb\"}]\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"1\",{\"charSet\":\"utf-8\"}],[\"$\",\"title\",\"2\",{\"children\":\"recce\"}],[\"$\",\"meta\",\"3\",{\"name\":\"description\",\"content\":\"Recce: Data validation toolkit for comprehensive PR review\"}],[\"$\",\"link\",\"4\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"type\":\"image/x-icon\",\"sizes\":\"32x32\"}]]\n4:null\n"])</script></body></html>
@@ -2,6 +2,6 @@
2
2
  3:I[1996,["266","static/chunks/e24bf851-0f8cbc99656833e7.js","517","static/chunks/c1ceaa8b-a1e442154d23515e.js","376","static/chunks/3a92ee20-3b5d922d4157af5e.js","455","static/chunks/6ef81909-694dc38134099299.js","678","static/chunks/3998a672-eaad84bdd88cc73e.js","509","static/chunks/9746af58-d74bef4d03eea6ab.js","648","static/chunks/ce84277d-f42c2c58049cea2d.js","989","static/chunks/47d8844f-79a1b53c66a7d7ec.js","147","static/chunks/a30376cd-7d806e1602f2dc3a.js","995","static/chunks/fee69bc6-f17d36c080742e74.js","739","static/chunks/7a8a3e83-d7fa409d97b38b2b.js","283","static/chunks/450c323b-1bb5db526e54435a.js","303","static/chunks/36e1c10d-bb0210cbd6573a8d.js","22","static/chunks/29e3cc0d-8c150e37dff9631b.js","25","static/chunks/b63b1b3f-7395c74e11a14e95.js","355","static/chunks/7f27ae6c-413f6b869a04183a.js","495","static/chunks/6dc81886-c94b9b91bc2c3caf.js","599","static/chunks/c132bf7d-8102037f9ccf372a.js","971","static/chunks/cd9f8d63-e020f408095ed77c.js","778","static/chunks/778-aef312bffb4c0312.js","931","static/chunks/app/page-7086764277331fcb.js"],"default",1]
3
3
  4:I[79137,[],""]
4
4
  5:I[63846,[],""]
5
- 0:["eIqnO-Nu8atPURSm-S7vW",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c9ecb46a4b21c126.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/88b8abc134cfd59a.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]]
5
+ 0:["POqJHyxRZAKc5Vb7Bi6Gz",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/c9ecb46a4b21c126.css","precedence":"next","crossOrigin":"$undefined"}]]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/88b8abc134cfd59a.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","children":["$","body",null,{"suppressHydrationWarning":true,"children":["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$L6",null]]]]
6
6
  6:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"recce"}],["$","meta","3",{"name":"description","content":"Recce: Data validation toolkit for comprehensive PR review"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"32x32"}]]
7
7
  1:null
@@ -74,8 +74,8 @@ def _diff_select_scope(old_scope: Scope, new_scope: Scope, scope_changes_map: di
74
74
  # check if the upstream scopes is not breaking
75
75
  for source_name, source in new_scope.sources.items():
76
76
  if scope_changes_map.get(source) is not None:
77
- chanage = scope_changes_map[source]
78
- if chanage.category == "breaking":
77
+ change = scope_changes_map[source]
78
+ if change.category == "breaking":
79
79
  change_category = "breaking"
80
80
 
81
81
  # check if non-select expressions are the same
@@ -0,0 +1,336 @@
1
+ import time
2
+ from dataclasses import dataclass
3
+ from typing import Dict, List, Literal, Optional
4
+
5
+ import sqlglot.expressions as exp
6
+ from sqlglot import Dialect, parse_one
7
+ from sqlglot.errors import OptimizeError, SqlglotError
8
+ from sqlglot.optimizer import Scope, traverse_scope
9
+ from sqlglot.optimizer.qualify import qualify
10
+
11
+ from recce.exceptions import RecceException
12
+ from recce.util import SingletonMeta
13
+
14
+
15
+ @dataclass
16
+ class CLLPerformanceTracking(metaclass=SingletonMeta):
17
+ lineage_start = None
18
+ lineage_elapsed = None
19
+ column_lineage_start = None
20
+ column_lineage_elapsed = None
21
+
22
+ total_nodes = None
23
+ sqlglot_error_nodes = 0
24
+ other_error_nodes = 0
25
+
26
+ def start_lineage(self):
27
+ self.lineage_start = time.perf_counter_ns()
28
+
29
+ def end_lineage(self):
30
+ if self.lineage_start is None:
31
+ return
32
+ self.lineage_elapsed = (time.perf_counter_ns() - self.lineage_start) / 1000000
33
+
34
+ def start_column_lineage(self):
35
+ self.column_lineage_start = time.perf_counter_ns()
36
+
37
+ def end_column_lineage(self):
38
+ if self.column_lineage_start is None:
39
+ return
40
+ self.column_lineage_elapsed = (time.perf_counter_ns() - self.column_lineage_start) / 1000000
41
+
42
+ def set_total_nodes(self, total_nodes):
43
+ self.total_nodes = total_nodes
44
+
45
+ def increment_sqlglot_error_nodes(self):
46
+ self.sqlglot_error_nodes += 1
47
+
48
+ def increment_other_error_nodes(self):
49
+ self.other_error_nodes += 1
50
+
51
+ def to_dict(self):
52
+ return {
53
+ "lineage_elapsed_ms": self.lineage_elapsed,
54
+ "column_lineage_elapsed_ms": self.column_lineage_elapsed,
55
+ "total_nodes": self.total_nodes,
56
+ "sqlglot_error_nodes": self.sqlglot_error_nodes,
57
+ "other_error_nodes": self.other_error_nodes,
58
+ }
59
+
60
+ def reset(self):
61
+ self.lineage_start = None
62
+ self.lineage_elapsed = None
63
+ self.column_lineage_start = None
64
+ self.column_lineage_elapsed = None
65
+
66
+ self.total_nodes = None
67
+ self.sqlglot_error_nodes = 0
68
+ self.other_error_nodes = 0
69
+
70
+
71
+ @dataclass
72
+ class ColumnLevelDependsOn:
73
+ node: str
74
+ column: str
75
+
76
+
77
+ @dataclass
78
+ class ColumnLevelDependencyColumn:
79
+ type: Literal["source", "passthrough", "renamed", "derived"]
80
+ depends_on: List[ColumnLevelDependsOn]
81
+
82
+
83
+ @dataclass()
84
+ class CllResult:
85
+ # Model to column dependencies
86
+ depends_on: List[ColumnLevelDependsOn]
87
+
88
+ # Column to column dependencies
89
+ columns: Dict[str, ColumnLevelDependencyColumn]
90
+
91
+
92
+ def _cll_column(proj, table_alias_map) -> ColumnLevelDependencyColumn:
93
+ # given an expression, return the columns depends on
94
+ # [{node: table, column: column}, ...]
95
+ type = "source"
96
+ depends_on: List[ColumnLevelDependsOn] = []
97
+
98
+ # instance of Column
99
+ if isinstance(proj, exp.Alias):
100
+ # 'select a as b'
101
+ # 'select CURRENT_TIMESTAMP() as create_at'
102
+ root = proj.this
103
+
104
+ for expression in root.walk(bfs=False):
105
+ if isinstance(expression, exp.Column):
106
+ column = expression
107
+ alias = column.table
108
+
109
+ if alias is None:
110
+ table = next(iter(table_alias_map.values()))
111
+ else:
112
+ table = table_alias_map.get(alias, alias)
113
+ depends_on.append(ColumnLevelDependsOn(table, column.name))
114
+ if type == "source":
115
+ type = "passthrough"
116
+ elif isinstance(expression, (exp.Paren, exp.Identifier)):
117
+ pass
118
+ else:
119
+ type = "derived"
120
+
121
+ depends_on = _dedeup_depends_on(depends_on)
122
+
123
+ if len(depends_on) == 0:
124
+ type = "source"
125
+
126
+ if isinstance(proj, exp.Alias):
127
+ alias = proj
128
+ if type == "passthrough" and depends_on[0].column != alias.alias_or_name:
129
+ type = "renamed"
130
+
131
+ return ColumnLevelDependencyColumn(type=type, depends_on=depends_on)
132
+
133
+
134
+ def cll_old(sql, schema=None, dialect=None) -> Dict[str, ColumnLevelDependencyColumn]:
135
+ result = cll(sql, schema=schema, dialect=dialect)
136
+ return result.columns
137
+
138
+
139
+ def _dedeup_depends_on(depends_on: List[ColumnLevelDependsOn]) -> List[ColumnLevelDependsOn]:
140
+ # deduplicate the depends_on list
141
+ dedup_set = set()
142
+ dedup_list = []
143
+ for col_dep in depends_on:
144
+ node_col = col_dep.node + "." + col_dep.column
145
+ if node_col not in dedup_set:
146
+ dedup_list.append(col_dep)
147
+ dedup_set.add(node_col)
148
+ return dedup_list
149
+
150
+
151
+ def _dedeup_cll_result(cll_result: CllResult):
152
+ cll_result.depends_on = _dedeup_depends_on(cll_result.depends_on)
153
+ for column in cll_result.columns.values():
154
+ column.depends_on = _dedeup_depends_on(column.depends_on)
155
+
156
+
157
+ def _cll_set_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> CllResult:
158
+ result = CllResult(depends_on=[], columns={})
159
+ scope_lineage = result.columns
160
+
161
+ for union_scope in scope.union_scopes:
162
+ sub_scope_result = scope_cll_map.get(union_scope)
163
+
164
+ for k, v in sub_scope_result.columns.items():
165
+ if k not in result.columns:
166
+ scope_lineage[k] = v
167
+ else:
168
+ scope_lineage[k].depends_on.extend(v.depends_on)
169
+ scope_lineage[k].type = "derived"
170
+
171
+ result.depends_on.extend(sub_scope_result.depends_on)
172
+ return result
173
+
174
+
175
+ def _cll_select_scope(scope: Scope, scope_cll_map: dict[Scope, CllResult]) -> CllResult:
176
+ assert scope.expression.key == "select"
177
+
178
+ column_dep_map = {}
179
+ model_depends_on = []
180
+ table_alias_map = {t.alias_or_name: t.name for t in scope.tables}
181
+ select = scope.expression
182
+
183
+ def source_column_dependency(ref_column: exp.Column) -> Optional[ColumnLevelDependencyColumn]:
184
+ column_name = ref_column.name
185
+ table_name = ref_column.table if ref_column.table != "" else next(iter(table_alias_map.values()))
186
+ source = scope.sources.get(table_name, None) # type: exp.Table | Scope
187
+ if isinstance(source, Scope):
188
+ ref_cll = scope_cll_map.get(source)
189
+ if ref_cll is None:
190
+ return None
191
+ return ref_cll.columns.get(column_name)
192
+ elif isinstance(source, exp.Table):
193
+ return ColumnLevelDependencyColumn(
194
+ type="passthrough", depends_on=[ColumnLevelDependsOn(source.name, column_name)]
195
+ )
196
+ else:
197
+ return None
198
+
199
+ for proj in scope.expression.selects:
200
+ type = "source"
201
+ column_depends_on: List[ColumnLevelDependsOn] = []
202
+ root = proj.this if isinstance(proj, exp.Alias) else proj
203
+ for expression in root.walk(bfs=False):
204
+ if isinstance(expression, exp.Column):
205
+ ref_column_dependency = source_column_dependency(expression)
206
+ if ref_column_dependency is not None:
207
+ column_depends_on.extend(ref_column_dependency.depends_on)
208
+ if ref_column_dependency.type == "derived":
209
+ type = "derived"
210
+ elif ref_column_dependency.type == "renamed":
211
+ if type == "source" or type == "passthrough":
212
+ type = "renamed"
213
+ elif ref_column_dependency.type == "passthrough":
214
+ if type == "source":
215
+ type = "passthrough"
216
+ else:
217
+ column_depends_on.append(ColumnLevelDependsOn(expression.table, expression.name))
218
+ if type == "source":
219
+ type = "passthrough"
220
+
221
+ elif isinstance(expression, (exp.Paren, exp.Identifier)):
222
+ pass
223
+ else:
224
+ type = "derived"
225
+
226
+ column_depends_on = _dedeup_depends_on(column_depends_on)
227
+
228
+ if len(column_depends_on) == 0 and type != "source":
229
+ type = "source"
230
+
231
+ if isinstance(proj, exp.Alias):
232
+ alias = proj
233
+ if type == "passthrough" and column_depends_on[0].column != alias.alias_or_name:
234
+ type = "renamed"
235
+
236
+ column_dep_map[proj.alias_or_name] = ColumnLevelDependencyColumn(type=type, depends_on=column_depends_on)
237
+
238
+ def selected_column_dependency(ref_column: exp.Column) -> Optional[ColumnLevelDependencyColumn]:
239
+ column_name = ref_column.name
240
+ return column_dep_map.get(column_name)
241
+
242
+ # joins clause: Reference the source columns
243
+ if select.args.get("joins"):
244
+ joins = select.args.get("joins")
245
+ for join in joins:
246
+ if isinstance(join, exp.Join):
247
+ for ref_column in join.find_all(exp.Column):
248
+ if source_column_dependency(ref_column) is not None:
249
+ model_depends_on.extend(source_column_dependency(ref_column).depends_on)
250
+
251
+ # where clauses: Reference the source columns
252
+ if select.args.get("where"):
253
+ where = select.args.get("where")
254
+ if isinstance(where, exp.Where):
255
+ for ref_column in where.find_all(exp.Column):
256
+ if source_column_dependency(ref_column) is not None:
257
+ model_depends_on.extend(source_column_dependency(ref_column).depends_on)
258
+
259
+ # group by clause: Reference the source columns, column index
260
+ if select.args.get("group"):
261
+ group = select.args.get("group")
262
+ if isinstance(group, exp.Group):
263
+ for ref_column in group.find_all(exp.Column):
264
+ if source_column_dependency(ref_column) is not None:
265
+ model_depends_on.extend(source_column_dependency(ref_column).depends_on)
266
+
267
+ # having clause: Reference the source columns, selected columns
268
+ if select.args.get("having"):
269
+ having = select.args.get("having")
270
+ if isinstance(having, exp.Having):
271
+ for ref_column in having.find_all(exp.Column):
272
+ if source_column_dependency(ref_column) is not None:
273
+ model_depends_on.extend(source_column_dependency(ref_column).depends_on)
274
+ elif selected_column_dependency(ref_column) is not None:
275
+ model_depends_on.extend(selected_column_dependency(ref_column).depends_on)
276
+
277
+ # order by clause: Reference the source columns, selected columns, column index
278
+ if select.args.get("order"):
279
+ order = select.args.get("order")
280
+ if isinstance(order, exp.Order):
281
+ for ref_column in order.find_all(exp.Column):
282
+ if source_column_dependency(ref_column) is not None:
283
+ model_depends_on.extend(source_column_dependency(ref_column).depends_on)
284
+ elif selected_column_dependency(ref_column) is not None:
285
+ model_depends_on.extend(selected_column_dependency(ref_column).depends_on)
286
+
287
+ for source in scope.sources.values():
288
+ scope_result = scope_cll_map.get(source)
289
+ if scope_result is not None:
290
+ model_depends_on.extend(scope_result.depends_on)
291
+
292
+ model_depends_on = _dedeup_depends_on(model_depends_on)
293
+
294
+ return CllResult(columns=column_dep_map, depends_on=model_depends_on)
295
+
296
+
297
+ def cll(sql, schema=None, dialect=None) -> CllResult:
298
+ # given a sql, return the cll for the sql
299
+ # {
300
+ # 'depends_on': [{'node': 'model_id', 'column': 'column'}],
301
+ # 'columns': {
302
+ # 'column1': {
303
+ # 'type': 'derived',
304
+ # 'depends_on': [{'node': 'model_id', 'column': 'column'}],
305
+ # }
306
+ # }
307
+ # }
308
+
309
+ dialect = Dialect.get(dialect) if dialect is not None else None
310
+
311
+ try:
312
+ expression = parse_one(sql, dialect=dialect)
313
+ except SqlglotError as e:
314
+ raise RecceException(f"Failed to parse SQL: {str(e)}")
315
+
316
+ try:
317
+ expression = qualify(expression, schema=schema, dialect=dialect)
318
+ except OptimizeError as e:
319
+ raise RecceException(f"Failed to optimize SQL: {str(e)}")
320
+ except SqlglotError as e:
321
+ raise RecceException(f"Failed to qualify SQL: {str(e)}")
322
+
323
+ result = CllResult(depends_on=[], columns={})
324
+ scope_cll_map = {}
325
+ for scope in traverse_scope(expression):
326
+ scope_type = scope.expression.key
327
+ if scope_type == "union" or scope_type == "intersect" or scope_type == "except":
328
+ result = _cll_set_scope(scope, scope_cll_map)
329
+ elif scope_type == "select":
330
+ result = _cll_select_scope(scope, scope_cll_map)
331
+ else:
332
+ continue
333
+
334
+ scope_cll_map[scope] = result
335
+
336
+ return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: recce-nightly
3
- Version: 1.4.0.20250519
3
+ Version: 1.4.0.20250520
4
4
  Summary: Environment diff tool for dbt
5
5
  Home-page: https://github.com/InfuseAI/recce
6
6
  Author: InfuseAI Dev Team
@@ -31,6 +31,8 @@ recce/data/404.html
31
31
  recce/data/favicon.ico
32
32
  recce/data/index.html
33
33
  recce/data/index.txt
34
+ recce/data/_next/static/POqJHyxRZAKc5Vb7Bi6Gz/_buildManifest.js
35
+ recce/data/_next/static/POqJHyxRZAKc5Vb7Bi6Gz/_ssgManifest.js
34
36
  recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js
35
37
  recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js
36
38
  recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js
@@ -66,8 +68,6 @@ recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js
66
68
  recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js
67
69
  recce/data/_next/static/css/88b8abc134cfd59a.css
68
70
  recce/data/_next/static/css/c9ecb46a4b21c126.css
69
- recce/data/_next/static/eIqnO-Nu8atPURSm-S7vW/_buildManifest.js
70
- recce/data/_next/static/eIqnO-Nu8atPURSm-S7vW/_ssgManifest.js
71
71
  recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2
72
72
  recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff
73
73
  recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff
@@ -1 +0,0 @@
1
- 1.4.0.20250519